简体   繁体   English

ld报告对nm找到的符号的未定义引用

[英]ld reports undefined reference to symbol found by nm

I am building a shared library with the following instructions : 我正在按照以下说明构建共享库:

cc -shared -Wl,-soname,libmy.so.0 [lots of .o files] -o libmy.so.0
ln -f -s libmy.so.0 libmy.so

I don't know if this is important, but this library is written in C. 我不知道这是否重要,但是这个库是用C编写的。

I then try to link with this library, from a C++ program : 然后,我尝试从C ++程序链接到该库:

/usr/bin/c++ -g CMakeFiles/codegen.dir/client/codegen.cpp.o CMakeFiles/codegen.dir
 /namenode/shared_objects.cpp.o  -o codegen -rdynamic -L/path/to/libmy -lpthread
 -lboost_system-mt -lboost_filesystem-mt -lboost_unit_test_framework-mt
 -lboost_serialization-mt -lmy -Wl,-rpath,/path/to/libmy

But ld reports an error : 但是ld报告一个错误:

CMakeFiles/codegen.dir/client/codegen.cpp.o: In function `main':
[...]/src/client/codegen.cpp:46:
   undefined reference to `alloc_code(int, int, int, int, int)'

Even if alloc_code appears to be in the shared library: 即使alloc_code似乎位于共享库中:

$ nm libmy.so | grep alloc_code
0000000000002c80 T alloc_code

Note that libmy.so and my codegen program are compiled using different compiler flags (one is compiled in debug mode while the other is compiled in optimized mode), but I don't think the issue comes from here. 需要注意的是libmy.so和我codegen程序都在使用不同的编译器标志(一个在调试模式下进行编译,而另一种是在优化模式编译)编译的,但我不认为这个问题来自于这里。

What could make ld unable to link codegen with libmy.so ? 什么可以让ld无法链接codegenlibmy.so

Your C function needs to be declared to C++ as this: 您的C函数需要这样声明为C ++:

#ifdef __cplusplus
extern "C" {
#endif

void alloc_code(int, int, int, int, int);

#ifdef __cplusplus
}
#endif

Otherwise, the compiler and thus linker assume C++ linkage (where multiple functions can exist with the same name so long as their arguments differ) - and will search for the "C++-mangled" variant of the function. 否则,编译器和链接器将假定为C ++链接(只要参数不同,多个函数可以使用相同的名称存在)-并将搜索该函数的“ C ++缠结”变体。

When using extern "C" you tell the compiler and linker to use the unmangled "C" name. 使用extern "C"您告诉编译器和链接器使用完整的“ C”名称。

To demonstrate this, let's write the same "library" and compile it with both a C compiler and a C++ compiler: 为了演示这一点,让我们编写相同的“库”,并使用C编译器和C ++编译器进行编译:

/* Library Source Code */
int library_function(void) {
    return 0;
}

Then compile with C: 然后用C编译:

gcc -o libdummy.so -shared -fPIC dummy-library.c
nm libdummy.so | grep library_function

Which outputs: 哪个输出:

0000000000000640 T library_function

Running the same thing with a C++ compiler yields: 使用C ++编译器运行同一件事会产生:

g++ -o libdummy.so -shared -fPIC dummy-library.c
nm libdummy.so

=> =>

0000000000000670 T _Z16library_functionv

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM