如何将第三方C++源代码编译为共享库



我下载了第三方源代码EDFlib,并希望(使用Visual Studio)将其编译到一个共享库中,并导出所有符号。

头文件如下:

#ifdef __cplusplus
extern "C" {
#endif
...
long long edftell(int handle, int edfsignal);
...

#ifdef __cplusplus
}
#endif

当我在VisualStudio中编译头文件和源文件时,不会生成.lib(可能意味着不会导出任何符号)。

是否可以在不修改库头文件的情况下将其编译成一个导出了所有符号的共享库?当第三方团队发布新版本时,这将使切换到新版本变得容易。

注:

如果我自己创建了这个库,我会这样做:

#ifdef WIN32
    #ifdef EDFLIB_EXPORTS
        #define EDFLIB_API __declspec(dllexport)
    #else
        #define EDFLIB_API __declspec(dllimport)
    #endif
#else 
    #define EDFLIB_API
#endif
long long EDFLIB_API edftell(int handle, int edfsignal);

可以使用这些导出标志修改库头文件,但我不想修改它,我想找到一个替代方案。

对于更大的库,一个可能的解决方案是将此任务自动化,但这可能不像看起来那么容易(C++中的非POD数据,enums,…)

如果您使用一些最新的GCC(例如在Linux上)进行编译,您可以使用我的GCC MELT工具对其进行自定义,也许可以让它生成一些ed脚本来修补标头。这不是一项容易的任务(可能需要几周的工作),我建议只对一个相当大的库(例如,一百万行C++)这样做,即使在这种情况下,也不值得为此付出代价来部分自动化。。。。

对于您的EDFlib,最简单的方法是修补他们的EDFlib.h文件(您可能需要在大约30个声明中添加EDFLIB_API),并在github上发出pull请求。

真正的问题是,Windows和POSIX(至少是Linux和大多数类似Unix的AIX、Solaris、HPUX)在链接器的角色和动态库(以及其中的符号)的性质方面具有不兼容的视图。Levine的《链接器和装载器》一书对此进行了详细解释。这也是为什么我对完全自动化的方法持怀疑态度(开发人员是唯一知道应该导出什么以及如何导出的人;因此对于您的库,您需要对声明进行注释以导出;最后,为C++库制作与C兼容的API通常需要重新设计和代码重构)。

注:。GCC MELT是GCC的插件,GCC不允许在Windows上使用插件(但允许在Linux上使用插件),正是因为你遇到了一个问题:用__declspec(dllexport)装饰每个导出的函数太痛苦了。

最新更新