对从静态库直接创建的共享库中的函数的未定义引用

时间:2015-11-13 05:48:15

标签: c++ c linux

我有一个旧的静态库,其中包含一个简单的模拟器。通过调用库中也包含的函数(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。

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

感谢任何帮助或评论。

1 个答案:

答案 0 :(得分: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);