将DLL编译到静态库时,如何处理DLL_导出? 我在Visual C++ 2010中有一个项目,其中包含了一个密钥头文件中的预处理器指令。实际上,它是ZMQ源代码
项目通常配置为dll,因此标头使用dll\U导出的状态(已定义/未定义)。如果项目用于编译dll,则由于从zmq.h进行了以下设置,dll项目或客户端代码都可以使用标题:将DLL编译到静态库时,如何处理DLL_导出? 我在Visual C++ 2010中有一个项目,其中包含了一个密钥头文件中的预处理器指令。实际上,它是ZMQ源代码,c++,windows,static-libraries,dllexport,C++,Windows,Static Libraries,Dllexport,项目通常配置为dll,因此标头使用dll\U导出的状态(已定义/未定义)。如果项目用于编译dll,则由于从zmq.h进行了以下设置,dll项目或客户端代码都可以使用标题: #if defined _WIN32 # if defined DLL_EXPORT # define ZMQ_EXPORT __declspec(dllexport) # else # define ZMQ_EXPORT __declspec(dllimport) # endif 但是,
#if defined _WIN32
# if defined DLL_EXPORT
# define ZMQ_EXPORT __declspec(dllexport)
# else
# define ZMQ_EXPORT __declspec(dllimport)
# endif
但是,这不支持我正在构建静态库的设置。因此,我必须手动修改标题。
Visual studio似乎能够识别dll项目设置,并相应地处理dll_导出的定义。是否有visual studio可以识别的符号对应于静态库设置?基本上,我希望通过扩展上述代码片段中使用的方法来处理静态库编译和使用。\uu declspec(dllimport)
是完全可选的。构建DLL时,链接器还会创建一个静态导入库
如果在编译客户端代码时不使用\uu declspec(dllimport)
,则它与fat静态库或静态导入库兼容。链接器会把一切弄清楚的
因此,我建议:
# if defined DLL_EXPORT
# define ZMQ_EXPORT __declspec(dllexport)
# else
# define ZMQ_EXPORT extern
# endif
正如@vanza指出的,您需要消除任何数据导出(您可以简单地将它们包装在访问器函数中)。无论如何,您都应该这样做,因为数据导出是脆弱的
注意:
\uu declspec(dllimport)
导致函数调用速度稍快,这是在使用静态库的灵活性与调用DLL的性能非常小的提高之间的折衷。我只想介绍第二个(可选)宏,类似于ZMQ\u static
:
#if defined(ZMQ_STATIC)
# define ZMQ_EXPORT
#elif defined(DLL_EXPORT)
# define ZMQ_EXPORT __declspec(dllexport)
#else
# define ZMQ_EXPORT __declspec(dllimport)
#endif
在将库构建为静态库或将其作为静态库使用时定义所述宏。\u declspec(dllimport)仅适用于函数,但不适用于数据导出。@vanza:没错,但从DLL导出的数据非常少。它在其他方面也很脆弱。dllimport将函数名f修改为u imp_f。dllexport不会更改名称。因此,要从普通静态库中获取函数,请使用f(),并从导入库中获取函数,需要u imp_f(由u declspec(dllimport)生成)。所以你的意思是,当链接一个对象文件时,你可以提供普通的静态库和导入库,使用哪一个取决于对象文件;Visual Studio只需在
\u declspec(dllimport)
(用于链接到MSVC*.DLL)和blank(用于链接到静态CRT)之间切换。