【问题标题】:Windows dynamic library conditional compilation, and C++/C mixing questionWindows动态库条件编译,以及C++/C混合题
【发布时间】:2026-01-24 00:20:08
【问题描述】:

我正在尝试理解一些我继承的代码,但是在谷歌上搜索我的方法时遇到了一些问题,我有一些问题希望你们中的一些人能帮助我。代码如下所示,是一个声明函数的.hpp(c++头文件)。

#ifdef _MSC_VER
    #define EXPORT_SYMBOL __declspec(dllexport)
#else
    #define EXPORT_SYMBOL
#endif

#ifdef __cplusplus
extern "C" {
#endif

EXPORT_SYMBOL float func(int int_param, float float_param);

#ifdef __cplusplus
}
#endif

我的第一个困惑是

#ifdef _MSC_VER
    #define EXPORT_SYMBOL __declspec(dllexport)
#else
    #define EXPORT_SYMBOL
#endif

我将其理解为“如果我们是从 Windows 机器编译,请做一些特别的事情”。

  1. __declspec(dllexport) 究竟是做什么的?
  2. 为什么我需要 EXPORT_SYMBOL

其次,我对将标题包装在 extern "C" 语句中的必要性感到困惑。据我所知,头文件正在检查是否定义了 __cplusplus,也就是说,我们是否使用 g++ 进行编译。 extern 块在这里是为了确保如果在一个名为 func.c 而不是 .cpp 文件的文件中找到 func() 然后编译,我不会遇到 g++ 编译器的问题与 gcc。我了解重载,以及 g++ 如何更改函数名称以启用重载。

  1. 由于我将它包含在一个 .cpp 文件中,因此打算用 g++ 专门编译它,我是否需要 extern "C" 块和 #ifdef 语句?有没有这种情况至关重要?

【问题讨论】:

标签: c++ c gcc dll g++


【解决方案1】:

__declspec(dllexport) 究竟做了什么?

创建 DLL 时,默认情况下不导出任何符号(与静态库不同)。在 Visual C++ 中,__declspec(dllexport) 是导出符号的最简单方法。还有其他导出方式。

因为我将它包含在 .cpp 文件中,因此打算专门 用 g++ 编译它,我需​​要 extern "C" 块和#ifdef 陈述?有没有这种情况至关重要?

如果您从 C 程序、由任何编译器构建的 C++ 程序甚至从具有 C 绑定的其他语言加载 DLL,这将允许使用该函数。如果您只使用 C++ 和 g++ 编译器,那么在某些情况下这很重要:动态加载 DLL - 在这种情况下,您需要将函数名称作为字符串提供(除非您使用 extern "C",否则会被破坏)。

【讨论】: