3

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

4

2 回答 2

9

I would just introduce a second (optional) macro, something like 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

Define said macro both when building your library as a static library or when consuming it as a static library.

于 2011-06-06T23:52:31.667 回答
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 的性能提升很小之间进行权衡。

于 2011-06-06T23:34:26.027 回答