未定义的引用错误,但库中存在符号

The*_*eer 7 c linker gcc

我收到undefined reference以下示例的错误。我看到了很多与这个问题相关的问题,但相信我给出了一个剥离的、可重复的、概念性的例子,而不是其他问题中的具体问题,

dynlib.h:

void printMe_dyn();
Run Code Online (Sandbox Code Playgroud)

dynlib.c:

#include <stdio.h>
#include "dynlib.h"

void printMe_dyn() {
  printf("I am execuded from a dynamic lib");
}
Run Code Online (Sandbox Code Playgroud)

myapp.c:

#include <stdio.h>
#include "dynlib.h"

int main() 
{
    printMe_dyn();
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

构建步骤:

gcc -Wall -fpic -c dynlib.c
gcc -shared -o libdynlib.so dynlib.o
gcc -Wall -L. -ldynlib myapp.c -o myapp
Run Code Online (Sandbox Code Playgroud)

错误:

/tmp/ccwb6Fnv.o: In function `main':
myapp.c:(.text+0xa): undefined reference to `printMe_dyn'
collect2: error: ld returned 1 exit status
Run Code Online (Sandbox Code Playgroud)

证明该符号在库中:

nm libdynlib.so | grep printMe_dyn
00000000000006e0 T printMe_dyn
Run Code Online (Sandbox Code Playgroud)
  1. 我是否使用正确的编译器标志来构建动态库?
  2. 我所提供的证据真的是明确的证据吗?
  3. 可以采取什么其他方法来诊断问题?

Sou*_*osh 5

库的出现顺序很重要

引用在线gcc手册

在命令中编写此选项的位置会有所不同;链接器按照指定的顺序搜索和处理库和目标文件。因此,在文件之后但在.之前foo.o -lz bar.o搜索库。如果引用 中的函数,则可能不会加载这些函数。zfoo.obar.obar.oz

您应该将编译语句更改为

gcc -o myapp -Wall -L. myapp.c -ldynlib 
Run Code Online (Sandbox Code Playgroud)

告诉gcc搜索(编译)中使用的符号myapp.c出现在dynlib.


Ale*_*nko 5

正如附加通知一样。当库由 gcc 构建并链接到 c++ 项目时,可能会获得相同的行为。如下:

gcc -Wall -fpic -c dynlib.c
gcc -shared -o libdynlib.so dynlib.o
g++ -o myapp -Wall -L. myapp.cpp -ldynlib
Run Code Online (Sandbox Code Playgroud)

在这种情况下,原因是 g++ 使用的名称修改。要关闭它,必须在extern "C"C 库中包装 C 函数原型。例如如下:

dynlib.h:

#ifdef __cplusplus
extern "C"{
#endif
void printMe_dyn();
#ifdef __cplusplus
}
#endif
Run Code Online (Sandbox Code Playgroud)