我正在将一些C++代码编译到库中。假设我的源文件mylib.cpp
且util.cpp
。util.cpp
中的代码用于库实现,但不是库的一部分,因为使用该库的代码不能调用它(它不在公共标头中(,并且不应知道它的存在;但my_lib.cpp
包括util.hpp
,并且依赖于编译util.cpp
目标代码。
现在,如果我编译mylib.o
并util.o
,则执行:
ar qc libmylib.a mylib.o util.o
我的库工作得很好;但是 - 实用程序代码作为符号公开。因此,如果我将此库与其他一些代码链接,则可能会出现双重定义的冲突。或者其他代码可能不恰当地依赖于可用的符号(例如,具有自己的标头(。
如何确保只有mylib.o
(和util.o
(中的目标代码才能"看到"util.o
中的符号,而外部代码则不会?
注意:我相信这个问题也适用于C语言,也许也适用于其他编译语言。
将注释转换为答案。
如果您的C++库有自己的命名空间,那么使用该命名空间或子命名空间名义上是控制对内部实用程序的访问的正确方法。 听起来好像你的代码没有提供模板类——这些约束必须单独考虑。
如果隐私是一个主要问题,我可能会考虑将util.cpp
(以及util.hpp
(包含在具有适当命名空间控件的mylib.cpp
(意味着#include "util.cpp"
(的源代码中,以便来自util.cpp
的代码在mylib.cpp
内部可用,但在外部不可用(使用匿名命名空间,或namespace mylib::Private
或某些此类方案(。这不是很传统,但它可能是有效的(一旦你制定了必要的调整(。组合 TU(翻译单元(可能没有大到导致编译器出现重大问题的程度。这不依赖于编译器扩展。
这是我的后备"解决方案",它实际上是一种解决方法:
我保持公众可见性,但我util.cpp
的所有代码都增加了一些命名元素,这将使它有效地唯一。例如,我可以用namespace mylib
将这些函数括起来。不是(去残(符号都是mylib::foo()
(或mylib::util::foo()
(。它们将被搜索,但可以合理地假设它们不会匹配 mylib 代码之外的任何内容。
除了麻烦之外,这还不利于仍然允许外部代码依赖于此内部实用程序代码 - 如果它是故意这样做的。