gpt4 book ai didi

c++ - ld undefined reference ,尽管找到了库并导出了符号

转载 作者:太空狗 更新时间:2023-10-29 23:13:22 25 4
gpt4 key购买 nike

现在断断续续地与此抗争了 48 小时;尝试将动态库与其依赖项链接时,我仍然遇到 undefined reference 错误 - 尽管所有导出都存在,并且已成功找到该库。

场景:

  • libmemory (C++) - 使用 extern "C" 导出函数
  • libstring (C) - 导出函数,从 libmemory 导入

libmemory 构建成功:

$ g++ -shared -fPIC -o ./builds/libmemory.so ...$(OBJECTS)...

libstring 编译成功,但链接失败:

$ gcc -shared -fPIC -o ./builds/libstring.so ...$(OBJECTS)... -L./builds -lmemory
./temp/libstring/string.o: In function `STR_duplicate':
string.c:(.text+0x1cb): undefined reference to `MEM_priv_alloc'
./temp/libstring/string.o: In function `STR_duplicate_replace':
string.c:(.text+0x2a0): undefined reference to `MEM_priv_free'
string.c:(.text+0x2bf): undefined reference to `MEM_priv_alloc'
/usr/bin/ld: ./builds/libstring.so: hidden symbol `MEM_priv_free' isn't defined
/usr/bin/ld: final link failed: Bad value
collect2: error: ld returned 1 exit status

验证 libmemory 导出其符号,并通过使用 -v 到 gcc 找到库本身:

...
attempt to open ./builds/libmemory.so succeeded
-lmemory (./builds/libmemory.so)
...

$ nm -gC ./builds/libmemory.so | grep MEM_
0000000000009178 T MEM_exit
0000000000009343 T MEM_init
00000000000093e9 T MEM_print_leaks
00000000000095be T MEM_priv_alloc
000000000000971d T MEM_priv_free
00000000000099c1 T MEM_priv_realloc
0000000000009d26 T MEM_set_callback_leak
0000000000009d3f T MEM_set_callback_noleak

$ objdump -T ./builds/libmemory.so | grep MEM_
0000000000009d3f g DF .text 0000000000000019 Base MEM_set_callback_noleak
00000000000093e9 g DF .text 00000000000001d5 Base MEM_print_leaks
0000000000009d26 g DF .text 0000000000000019 Base MEM_set_callback_leak
00000000000099c1 g DF .text 0000000000000365 Base MEM_priv_realloc
0000000000009343 g DF .text 00000000000000a6 Base MEM_init
00000000000095be g DF .text 000000000000015f Base MEM_priv_alloc
000000000000971d g DF .text 00000000000002a4 Base MEM_priv_free
0000000000009178 g DF .text 00000000000000a7 Base MEM_exit

$ readelf -Ws ./builds/libmemory.so | grep MEM_
49: 0000000000009d3f 25 FUNC GLOBAL DEFAULT 11 MEM_set_callback_noleak
95: 00000000000093e9 469 FUNC GLOBAL DEFAULT 11 MEM_print_leaks
99: 0000000000009d26 25 FUNC GLOBAL DEFAULT 11 MEM_set_callback_leak
118: 00000000000099c1 869 FUNC GLOBAL DEFAULT 11 MEM_priv_realloc
126: 0000000000009343 166 FUNC GLOBAL DEFAULT 11 MEM_init
145: 00000000000095be 351 FUNC GLOBAL DEFAULT 11 MEM_priv_alloc
192: 000000000000971d 676 FUNC GLOBAL DEFAULT 11 MEM_priv_free
272: 0000000000009178 167 FUNC GLOBAL DEFAULT 11 MEM_exit
103: 0000000000009343 166 FUNC GLOBAL DEFAULT 11 MEM_init
108: 0000000000009178 167 FUNC GLOBAL DEFAULT 11 MEM_exit
148: 0000000000009d3f 25 FUNC GLOBAL DEFAULT 11 MEM_set_callback_noleak
202: 00000000000095be 351 FUNC GLOBAL DEFAULT 11 MEM_priv_alloc
267: 000000000000971d 676 FUNC GLOBAL DEFAULT 11 MEM_priv_free
342: 0000000000009d26 25 FUNC GLOBAL DEFAULT 11 MEM_set_callback_leak
346: 00000000000099c1 869 FUNC GLOBAL DEFAULT 11 MEM_priv_realloc
366: 00000000000093e9 469 FUNC GLOBAL DEFAULT 11 MEM_print_leaks

我是否遗漏了一些非常简单的东西?所有其他与此相关的问题都有简单的答案,例如链接库顺序和使用的路径 - 但我已经验证它们已到位并按预期工作。

修改 -fvisibility 也没有导致任何变化。

无论使用clang还是gcc,结果都是一样的。

Linux 3.16.0-38-genericgcc 版本 4.8.4 (Ubuntu 4.8.4-2ubuntu1~14.04.3)

最佳答案

你应该标记MEM_priv_alloc()用作extern "C"或将函数体包装成 extern "C" { /* function implementation */ } (已经完成,正如我从描述中看到的那样)。并使用 __cplusplus 的组合和 extern "C"在标题中

#ifdef __cplusplus
#define EXTERNC extern "C"
#else
#define EXTERNC
#endif

EXTERNC int MEM_priv_alloc (void);

请仔细检查如何 MEM_priv_alloc原型(prototype)完成。例如,MEM_priv_alloc应该inline (不幸的是,我不知道这方面的物理知识,但是 inline 示例对我来说失败了)


下面是对我有用的简化示例:

文件:

$ ls
main.c Makefile mem.cpp mem.h strings.c strings.h

内存.cpp

#include <stdio.h>
#include "mem.h"
extern "C" int MEM_priv_alloc (void)
{
return 0;
}

内存.h

#ifdef __cplusplus
#define EXTERNC extern "C"
#else
#define EXTERNC
#endif
EXTERNC int MEM_priv_alloc (void);

字符串.c:

#include <stdio.h>
#include "mem.h"
int STR_duplicate_replace (void)
{
MEM_priv_alloc();
}

字符串.h:

int STR_duplicate_replace (void);

主.c

#include <stdio.h>
#include "string.h"
int main (void)
{
STR_duplicate_replace ();
return 0;
}

生成文件:

prog: libmemory.so libstrings.so
gcc -o $@ -L. -lmemory -lstrings main.c

libmemory.so: mem.cpp
g++ -shared -fPIC -o $@ $^

libstrings.so: strings.c
gcc -shared -fPIC -o $@ $^

和构建日志:

g++ -shared -fPIC -o libmemory.so mem.cpp
gcc -shared -fPIC -o libstrings.so strings.c
gcc -o prog -L. -lmemory -lstrings main.c

另请参阅更多详细信息 Using C++ library in C codewiki How to mix C and C++

关于c++ - ld undefined reference ,尽管找到了库并导出了符号,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39866262/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com