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

发布于 2024-11-14 13:42:33 字数 525 浏览 4 评论 0原文

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

I have a project in visual c++ 2010, which contains preprocessor directives in a key header file. Actually, it is the ZMQ source code.

The project is normally configured to be a dll, so the header uses DLL_EXPORT's status (defined/not defined). If the project is used to compile a dll, the header can be used by both the dll project or the client code, thanks to the following setup taken from zmq.h:

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

However, this does not support the setup where I'm building a static library. Therefore I have to modify to header by hand.
Visual studio seems to recognize dll project setup and handle definitions for dll_export accordingly. Is there a symbol that is recognized by visual studio, that corresponds to static library setup? Basically, I'd like to handle static library compilation and usage by extending the method used in the above snippet.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

怀里藏娇 2024-11-21 13:42:33

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

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

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.

白龙吟 2024-11-21 13:42:33

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

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

所以我建议:

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

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


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

__declspec(dllimport) is completely optional. When you build the DLL, the linker also creates a static import library.

If you compile the client code without __declspec(dllimport), it is compatible with either a fat static library or a static import library. The linker will figure it all out.

So I suggest:

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

As @vanza points out, you'll need to eliminate any data exports (you can trivially wrap them in accessor functions). You should do that anyway, data exports are fragile.


Note: __declspec(dllimport) results in slightly faster function calls, it's a tradeoff between flexibility to use a static library vs a very small increase in performance calling the DLL.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文