我最近不得不面对一个关于lib管理的相当复杂的问题,但如果我是第一个,我会非常惊讶。
假设您正在C中创建一个名为lib1
的库(静态或动态),其中lib1
是通过API公开的一些函数,还有一些其他函数保持私有。
理想情况下,私有函数应该是static
。不幸的是,让我们假设一个名为extmod.c
的源文件来自另一个项目,保持它不被修改是有益的。因此,它定义的函数变得不实际。
因此,static
中定义的所有函数都存在于extmod
ABI中,而不是API中,因为相关的lib1
没有发布。所以没人注意到。
不幸的是,在后期,有人想同时链接*.h
和另一个lib1
,其中也包括lib2
。由于定义重复,导致链接错误。
在extmod
中,这个问题的答案是一个简单的名称空间。在C语言中,我们运气不太好。
有一些解决这个问题的方法,但我想探讨是否有人认为已经找到了一种有效和非侵入性的方法。我所说的“非侵入性”是指一种尽可能避免修改C++
的方法。
在可能的解决方法中,可以使用不同的前缀将所有定义从extmod.c
更改为,从而有效地模拟命名空间。或者将extmod.c
的内容放入extmod.c
并静态化所有内容的可能性。这两种方法都做了广泛的修改。。。
注意,我已经看了this previous answer,但它没有解决这个具体问题。
最佳答案
您可以通过将extmod.c从构建中排除并以某种方式将其作为头文件来实现“不同前缀”解决方案。使用C预处理器有效地修改文件而不实际修改它。例如,如果extmod.c包含:
void print_hello()
{
printf("hello!");
}
从生成中排除此文件并添加一个名为ns_extmod.c的文件。此文件的内容应如下所示:
#define print_hello ns_print_hello
#include "extmod.c"
编译时,C预处理器会将print_hello重命名为ns_print_hello,但原始文件将保持不变。
或者,如果且仅当extmod.c不在内部调用函数时,可以使用预处理器以相同的方式使其静态:
#define print_hello static print_hello
#include "extmod.c"
如果您可以控制构建过程,那么这应该对您有用。