如何在 C++ 静态库中隐藏符号?
Posted
技术标签:
【中文标题】如何在 C++ 静态库中隐藏符号?【英文标题】:How to hide symbols in c++ static library? 【发布时间】: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);
。
【参考方案1】:
您违反了definition rule。简而言之,就是每个函数(1) 只能定义一次(除非声明为内联,在这种情况下,所有定义都必须相同)。
您尝试做的是惯用的命名空间。您的 A、B、C 库将在适当的命名空间中声明它们的所有函数。
类似
namespace A
int add(int lhs, int rhs);
;
namespace C
int add(int lhs, int rhs);
(1) 单一定义规则不仅仅与函数有关。在程序级别,它也适用于变量,并且在给定的翻译单元中,它也扩展到模板、类类型和枚举。
【讨论】:
以上是关于如何在 C++ 静态库中隐藏符号?的主要内容,如果未能解决你的问题,请参考以下文章
与静态库中的 std::string 相关的 C++ 未定义符号