强制使用GCC从链接的静态库导出特定的可见符号(同时排除其他符号)

时间:2013-12-03 08:42:28

标签: c gcc static-libraries visibility

我试图提供对从静态库链接到可执行文件的函数的访问。原始静态库定义了没有访问说明符的符号,并且我能够使用定义的here方法访问该函数,使用MSVC可以正常工作,因为默认情况下隐藏符号中的链接。

但是,在使用GCC时,我需要在使用-Wl, - exclude-libs,ALL时导出该函数,以防止所有其他不必要的符号从链接静态库中可见地导出。有问题的符号未从主应用程序本身引用,但第三方模块可能会尝试在外部动态使用该符号(ffi等),因此使用FORCE_UNDEFINED_SYMBOL。

我需要导出的唯一符号是主应用程序中标记的可见性默认值,以及静态库中的某些导入函数(我可能无法修改)。我知道可以使用包装函数,但是我想知道是否还有其他方法。

那么,是否可以从链接静态库中导出符号(可见),同时使用-WL, - exclude-libs,ALL,而不使用任何其他(版本列表等)文件,或命令/标志? (并且不修改静态库)

使用以下宏(部分)工作,但原始函数符号仍然是.hidden(将__MyFunction_fp导出为可见)。

#define APIEXPORT __attribute__ ((visibility ("default")))
#define FORCE_UNDEFINED_SYMBOL(x) extern APIEXPORT void x(void); APIEXPORT void* __ ## x ## _fp =(void*)&x;
FORCE_UNDEFINED_SYMBOL(MyFunction)

在这种情况下,MyFunction的实际定义/声明将存在于静态库中,并且无法更改。

编辑:我发现上面的宏FORCE_UNDEFINED_SYMBOL在MSVC下没有产生所需的符号可见性。似乎唯一可行的解​​决方案是使用编译指示注释,即__pragma(注释(链接器,“/ export:”#x))。也许gcc / ld存在类似的解决方案。

1 个答案:

答案 0 :(得分:0)

即使你成功了,你的建议听起来也难以维持。您希望与静态库共享对象(DLL)行为。

当我遇到类似问题时(例如第三方静态库),我将lib包装在共享对象中,并将其与我的应用程序一起使用。