在将dll编译为静态库时,如何处理DLL_EXPORT?

时间:2011-06-06 23:09:52

标签: c++ windows static-libraries dllexport

我在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的定义。是否有一个被visual studio识别的符号,它对应于静态库设置?基本上,我想通过扩展上面代码片段中使用的方法来处理静态库编译和使用。

2 个答案:

答案 0 :(得分:8)

我只想介绍第二个(可选)宏,例如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

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

答案 1 :(得分:2)

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

如果编译的客户端代码没有__declspec(dllimport),则它与胖静态库或静态导入库兼容。链接器将全部解决。

所以我建议:

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

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


注意:__declspec(dllimport)导致函数调用稍微快一些,这是在使用静态库的灵活性与调用DLL的性能的极小增加之间的权衡。