【问题标题】:undefined reference to function in shared library created directly from static library对直接从静态库创建的共享库中的函数的未定义引用
【发布时间】:2015-11-13 05:48:14
【问题描述】:

我有一个旧的静态库,其中包含一个简单的模拟器。通过调用库中也包含的函数 (sim) 来启动模拟器。现在,我正在尝试将这个静态库变成一个动态库:

g++ -shared -fPIC -o libdynamicSimulator.so -Wl,--whole-archive libstaticSimulator.a -Wl,--no-whole-archive

./libstaticSimulator.a 中的目标文件也使用 -fPIC 标志编译。此步骤工作正常,没有编译器/链接器错误。这一步我关注a SO post

但是,当我尝试通过从 main 调用 sim 函数来测试共享库时遇到链接器错误:

g++ -O2 -g -m64 -Wall -fno-strict-aliasing   -c -o main.o main.c
g++ -O2 -g -m64 -Wall -fno-strict-aliasing -L. main.o  -o sim_dynlib -ldynamicSimulator -lm -lpthread
main.o: In function `main':
main.c:40: undefined reference to `sim(unsigned long*, unsigned long*, unsigned long*, unsigned long)'
collect2: error: ld returned 1 exit status
make: *** [sim_dynlib] Error 1

我用nm来验证动态库中是否有符号:

$ nm ./libdynamicSimulator.so | grep sim 
0000000000102e10 T sim

该库是用 C++ 编写的,但 sim 的名称没有被破坏,因为它是在 extern "C" 块中定义的:

extern "C" {
  uint64_t sim(uint64_t *a1, uint64_t *a2, uint64_t *a3, uint64_t len)
  {
    ...
  }
}

下面是 main.c 声明和使用函数的方式:

extern uint64_t sim(uint64_t *a1, uint64_t *a2, uint64_t *a3, uint64_t len);

int main(int argc, char **argv)
{
  ... // preparing a1, a2, a3, len
  uint64_t act_sum = sim(a1, a2, a3, len);
  ...
}

我已经在谷歌上搜索了几个小时试图找到问题,但我能找到的只是在 g++ 命令行中重新排序 -l,我已经这样做了——在 main.o 之后 -ldynamicSimulator。

我觉得我在这里错过了一些非常简单/愚蠢的东西,但对于我的生活,我无法弄清楚它是什么。

感谢任何帮助或评论。

【问题讨论】:

  • 旧的静态库是在其他平台还是其他g++版本上编译的?
  • 您是否尝试在main.c 中使用uint64_t sim(uint64_t *a1, uint64_t *a2, uint64_t *a3, uint64_t len);(没有extern)?我想你有头文件...
  • 我没有使用头文件。但这应该没关系,因为我只是在做一个简单的理智测试。
  • 静态库是在另一个平台上编译的,但我在试图找出问题时在当前平台上再次编译。

标签: c++ c linux


【解决方案1】:

我想通了。我的感觉是正确的——这是一个愚蠢的错误:

main.c 中 sim() 函数的声明需要放入 extern "C" 块中,因为我使用 g++ 作为编译器。

extern "C" {
  extern uint64_t sim(uint64_t *a1, uint64_t *a2, uint64_t *a3, uint64_t len);
}
int main(int argc, char **argv)
{
  ... // preparing a1, a2, a3, len
  uint64_t act_sum = sim(a1, a2, a3, len);
  ...
}

此更改后链接器错误消失了。

另一个有效的简短声明:

extern "C" uint64_t sim(uint64_t *a1, uint64_t *a2, uint64_t *a3, uint64_t len);

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2015-11-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-09-30
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多