g++在动态库中生成错误的符号

发布于 2024-12-22 19:10:42 字数 633 浏览 1 评论 0原文

我正在尝试制作最简单的so库。

#include <stdio.h>
   void PutLoLoLo(){
   puts("Lololo");
}

使用 g++ 编译:

g++ -shared -fPIC main2.cpp -o simple.so -Wall

我在符号表中得到了这个:

:$ nm -D --dynamic --defined-only simple.so 
0000048c T _Z9PutLoLoLov
00002010 A __bss_start
00002010 A _edata
00002018 A _end
000004f8 T _fini
00000354 T _init

但我期望这样的结果:

0000048c T PutLoLoLo
00002010 A __bss_start
00002010 A _edata
00002018 A _end
000004f8 T _fini
00000354 T _init

所以,当然,当我尝试加载它时,我得到 dlopen() 错误。

请帮助我:我做错了什么?

I'm trying to make simplest so library.

#include <stdio.h>
   void PutLoLoLo(){
   puts("Lololo");
}

compiling with g++:

g++ -shared -fPIC main2.cpp -o simple.so -Wall

and I get this in symbol table:

:$ nm -D --dynamic --defined-only simple.so 
0000048c T _Z9PutLoLoLov
00002010 A __bss_start
00002010 A _edata
00002018 A _end
000004f8 T _fini
00000354 T _init

but I expect something like this:

0000048c T PutLoLoLo
00002010 A __bss_start
00002010 A _edata
00002018 A _end
000004f8 T _fini
00000354 T _init

So, of course, I get dlopen() error when I try to load it.

Please, help me: what am I doing wrong?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

晨敛清荷 2024-12-29 19:10:42

C++ mangle 符号名称。如果您想避免损坏,则必须将函数声明为 extern C,如下所示:

#include <stdio.h>
   extern "C" void PutLoLoLo(){
   puts("Lololo");
}

然后链接:

$ g++ -shared -fPIC lolo.cc -o lolo.so -Wall

将为您提供您所期望的内容:

$ nm -D --dynamic --defined-only ./lolo.so 
000000000000061c T PutLoLoLo
0000000000002018 A __bss_start
0000000000002018 A _edata
0000000000002028 A _end
0000000000000668 T _fini
0000000000000500 T _init

您将能够 dlopen 库并获取符号通过其“正常”名称。该函数仅限于具有 C 语义。因此,例如,您不能使用成员函数执行此操作,或者使用具有类语义的对象作为参数等。因此,如果您需要传入对象,则需要将这些参数视为 void *,并强制转换。

C++ mangles symbol names. If you want to avoid the mangling, the function must be declared as extern C, like so:

#include <stdio.h>
   extern "C" void PutLoLoLo(){
   puts("Lololo");
}

Then the link:

$ g++ -shared -fPIC lolo.cc -o lolo.so -Wall

Will give you what you expect:

$ nm -D --dynamic --defined-only ./lolo.so 
000000000000061c T PutLoLoLo
0000000000002018 A __bss_start
0000000000002018 A _edata
0000000000002028 A _end
0000000000000668 T _fini
0000000000000500 T _init

You will be able to dlopen the library and obtain the symbol via its 'normal' name. The function is restricted to having C semantics. So you can't, for instance, do this with member functions, or use objects with class semantics as arguments, etc. So if you need to pass in objects, you will need to take those arguments as void *, and cast.

三寸金莲 2024-12-29 19:10:42

这看起来就像 C++ 名称重整。试试这个:

extern "C" void PutLoLoLo(){
   puts("Lololo");
}

That looks like C++ name mangling. Try this:

extern "C" void PutLoLoLo(){
   puts("Lololo");
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文