2011-06-06 94 views
2

我在visual C++ 2010中有一个项目,其中包含关键头文件中的预处理器指令。实际上,它是ZMQ源代码。如何在编译DLL到静态库时处理DLL_EXPORT?

该项目通常配置为一个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的定义。有没有一个符号被视觉工作室认可,对应于静态库设置?基本上,我想通过扩展上面代码片段中使用的方法来处理静态库的编译和使用。

+0

我认为这不会有帮助; Visual Studio只需要在'_declspec(dllimport)'(用于链接到MSVC * .DLL)和空白(用于链接到静态CRT)之间切换。 – Neil 2011-06-06 23:37:04

回答

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 

定义说,构建库作为静态库或消费它作为一个静态库时,当宏观两者。

2

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

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

所以我建议:

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

由于@vanza所指出的,你需要消除所有的数据出口(你可以平凡包装他们在访问函数)。无论如何,你应该这样做,数据输出是脆弱的。


注:__declspec(dllimport)结果稍快函数调用,这是灵活运用静态库VS在性能上非常小的增加调用DLL之间的权衡。

+0

__declspec(dllimport)仅适用于函数,但不适用于数据导出。 – vanza 2011-06-06 23:36:00

+0

@vanza:你是对的,但是从DLL中导出的数据非常少见。它在其他方面也很脆弱。 – 2011-06-06 23:39:01

+0

dllimport *将函数名f修改为__imp_f。 dllexport不会更改名称。因此,要从普通静态库中获取函数f(),并从导入库中获取需要__imp_f(由__declspec(dllimport)生成)。所以你的意思是你可以在链接一个目标文件时提供普通的静态和导入库,并且使用哪一个取决于目标文件。 – Yttrill 2015-09-12 04:57:04