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

Undefined reference error but symbol existing in the library

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

dynlib.h:

void printMe_dyn();

dynlib.c:

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

void printMe_dyn() {
  printf("I am execuded from a dynamic lib");
}

myapp.c:

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

int main() 
{
    printMe_dyn();
    return 0;
}

构建步骤:

gcc -Wall -fpic -c dynlib.c
gcc -shared -o libdynlib.so dynlib.o
gcc -Wall -L. -ldynlib myapp.c -o myapp

错误:

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

符号在库中的证明:

nm libdynlib.so | grep printMe_dyn
00000000000006e0 T printMe_dyn
  1. 我是否使用了正确的编译器标志来构建动态 图书馆?
  2. 我给出的证明真的是明确的证明吗?
  3. 还有什么其他方法可以诊断问题?

库的出现顺序很重要

引用online gcc manual

It makes a difference where in the command you write this option; the linker searches and processes libraries and object files in the order they are specified. Thus, foo.o -lz bar.o searches library z after file foo.o but before bar.o. If bar.o refers to functions in z, those functions may not be loaded.

您应该将编译语句更改为

gcc -o myapp -Wall -L. myapp.c -ldynlib 

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

链接器命令行中库的顺序很重要。修复:

gcc -o myapp -Wall -L. myapp.c -ldynlib 

作为补充通知。当库由 gcc 构建并链接到 c++ 项目时,可能会出现相同的行为。如下:

gcc -Wall -fpic -c dynlib.c
gcc -shared -o libdynlib.so dynlib.o
g++ -o myapp -Wall -L. myapp.cpp -ldynlib

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

dynlib.h:

#ifdef __cplusplus
extern "C"{
#endif
void printMe_dyn();
#ifdef __cplusplus
}
#endif