将函数保密到 C 中的库中

Keep functions private into a lib in C

我最近不得不面对一个关于库管理的相当复杂的问题,但我会很惊讶成为第一个。

假设您正在 C 中创建一个名为 lib1 的库(静态或动态)。在 lib1 中有一些函数通过 API 公开,还有一些其他函数保持私有。

理想情况下,私有函数应该是 static。不幸的是,我们假设其中一个名为 extmod.c 的源文件来自另一个项目,并且最好不修改它。因此,static 它定义的函数变得不切实际。

因此,extmod 中定义的所有函数都出现在 lib1 ABI 中,但 API 中没有,因为相关的 *.h 未发布。所以没有人注意到。

不幸的是,在后期,有人想要 link 同时 lib1 和另一个 lib2,其中还包括 extmod。由于重复定义,它会导致 linking 错误。

C++中,这个问题的答案是一个简单的命名空间。在 C 中,我们就没那么幸运了。

这个问题有几个解决方案,但我想询问是否有人相信已经找到了一种有效且非侵入性的方法。 "non-invasive",我指的是一种尽可能避免修改 extmod.c.

的方法

在可能的解决方法中,可以使用不同的前缀更改 extmod.c 中的所有定义,从而有效地模拟命名空间。或者将 extmod.c 的内容放入 extmod.h 并静态化所有内容的可能性。这两种方法都广泛修改 extmod 虽然 ...

请注意,我查看了 this previous answer,但它没有解决这个具体问题。

您可以通过从您的构建中排除 extmod.c 并将其作为头文件以某种方式处理来实现您的 'different prefix' 解决方案。使用 C 预处理器可以有效地修改文件,而无需实际修改它。例如,如果 extmod.c 包含:

void print_hello()
{
   printf("hello!");
}

从您的构建中排除此文件并添加一个名为 ns_extmod.c 的文件。该文件的内容应如下所示:

#define print_hello ns_print_hello
#include "extmod.c"

在编译时,print_hello 将被 C 预处理器重命名为 ns_print_hello,但原始文件将保持不变。

或者,当且仅当函数未被 extmod.c 内部调用时,使用预处理器以相同的方式使它们成为静态的可能有效:

#define print_hello static print_hello
#include "extmod.c"

假设您可以控制构建过程,这应该对您有用。

无需实际编辑即可添加前缀的一种方法 extmod.c 如下:

创建一个新的头文件extmod_prefix.h为:

#ifndef EXTMOD_PREFIX_H
#define EXTMOD_PREFIX_H

#ifdef LIB1
#define PREFIX lib1_
#else
#ifdef LIB2
#define PREFIX lib2_
#endif
#endif

#define function_in_extmod PREFIX##function_in_extmod
/* Do this for all the functions in extmod.c */

#endif

将此文件包含在 extmod.h 中,并在 lib1 的构建过程中定义 LIB1,在 lib2 中定义 LIB2

这样,extmod.c中的所有函数将在 lib1 中以 lib1_ 为前缀,在 lib2 中以 lib2_ 为前缀。

Here's the answer(以问题的形式)。相关部分:

objcopy --prefix-symbols allows me to prefix all symbols exported by an object file / static library.