【发布时间】:2019-05-16 11:00:57
【问题描述】:
我会调整情况。 在这个问题中,我使用 Ubuntu 16.04 和 GCC 6.5.0 和 CMake 3.13.2。
我有 4 个静态库和一个可执行文件:A、B、C、D 和 main。
A 有 int add(int, int) 只需添加 2 个给定的整数。 B 有 int addb(int, int) 只需从 A 调用 add。
C 有 int add(int, int) 乘以 2 个给定的整数。
D 有 void print() 从 B 调用 addb 和从 C 调用 add。
而main 只需调用print()。
所有这些函数都将声明和定义拆分为.cpp 和.hpp。
方案:
A (add)
|
B (addb) C (add)
| |
|___________|
|
D (print)
|
main
我必须怎么做才能从A 符号中隐藏add?因为我在链接main时有多重定义。
如果我只是使用 cmake 构建,它会在两种情况下从 C 调用 add(参见 D 的 print())。我将B 与 ld (ld -static) 链接,但现在我有两个问题:
- 乘以
add的定义(首先定义在A) no .eh_frame_hdr table will be created
另外,我尝试使用 cmake 制作 A 和 C SHARED,但它像以前一样从 C 调用 add。
我除了 B 将是“完整的”静态库,没有 *UND*,如果我调用 addb,它将从 A 调用 add,add 将从 C 调用。
谢谢!
【问题讨论】:
-
这无法完成。您必须使用唯一的符号名称,以避免歧义。
-
这就是您要在 C++ 中使用命名空间的确切原因。如果多个库因为不使用不同的命名空间而输出相同(损坏的)符号名称,那么您就不走运了。
-
你不能破坏one definition rule。每个符号只能定义一次。 C++ 和库的典型解决方案是使用类或命名空间。然后你可以有例如
namespace A { int add(int, int); }和namespace C { int add(int, int); }。