将DLL编译为静态库时,如何处理DLL_EXPORT

How can I handle DLL_EXPORT when compiling dll to a static library?

本文关键字:DLL 处理 EXPORT 何处理 编译 静态      更新时间:2023-10-16

我在visual c++2010中有一个项目,它在一个键头文件中包含预处理器指令。实际上,它是ZMQ源代码。

项目通常配置为dll,因此标头使用dll_EXPORT的状态(已定义/未定义)。如果该项目用于编译dll,则dll项目或客户端代码都可以使用该标头,这要归功于从zmq.h获取的以下设置:

#if defined _WIN32
#   if defined DLL_EXPORT
#       define ZMQ_EXPORT __declspec(dllexport)
#   else
#       define ZMQ_EXPORT __declspec(dllimport)
#   endif

但是,这不支持我构建静态库的设置。因此,我不得不手动修改标题。Visual studio似乎能够识别dll项目设置并相应地处理dll_export的定义。有没有一个符号可以被visualstudio识别,对应于静态库设置?基本上,我想通过扩展上面片段中使用的方法来处理静态库的编译和使用。

我只想引入第二个(可选)宏,类似于ZMQ_STATIC:

#if defined(ZMQ_STATIC)
#    define ZMQ_EXPORT
#elif defined(DLL_EXPORT)
#    define ZMQ_EXPORT __declspec(dllexport)
#else
#    define ZMQ_EXPORT __declspec(dllimport)
#endif

在将库构建为静态库或将其作为静态库使用时,都要定义所述宏。

__declspec(dllimport)是完全可选的。构建DLL时,链接器还会创建一个静态导入库。

如果在不使用__declspec(dllimport)的情况下编译客户端代码,则它与胖静态库或静态导入库兼容。链接器会解决所有问题。

所以我建议:

#   if defined DLL_EXPORT
#       define ZMQ_EXPORT __declspec(dllexport)
#   else
#       define ZMQ_EXPORT extern
#   endif

正如@vanza所指出的,您需要消除任何数据导出(您可以简单地将它们封装在访问器函数中)。无论如何,你都应该这样做,数据导出是脆弱的。


注意:__declspec(dllimport)导致函数调用稍微快一点,这是在使用静态库的灵活性和调用DLL的性能小幅提高之间的权衡。