14
#if COMPILING_DLL
    #define DLLEXPORT __declspec(dllexport)
#else
    #define DLLEXPORT __declspec(dllimport)
#endif

我如何/在哪里定义COMPILING_DLL

在这里看到: __declspec(dllimport) 的真正含义是什么?

如果我不能使用相同的标头,听起来我根本不能使用加载时动态链接?

在此处输入图像描述

4

7 回答 7

17

另一种选择:

使用项目本地默认定义的宏。

您可以在以下位置查看项目本地默认定义的宏:

属性 -> C/C++ -> 预处理器 -> 预处理器定义。

例子:

假设您的项目名称是:MyDLL

该项目的默认宏本地:MYDLL_EXPORTS

 #ifdef  MYDLL_EXPORTS 
    /*Enabled as "export" while compiling the dll project*/
    #define DLLEXPORT __declspec(dllexport)  
 #else
    /*Enabled as "import" in the Client side for using already created dll file*/
    #define DLLEXPORT __declspec(dllimport)  
 #endif
于 2014-06-13T15:33:56.433 回答
14

定义的最佳位置COMPILING_DLL=1是编译器的命令行。如果您使用 Visual Studio IDE,那么它位于项目属性 ... C/C++ ... 预处理器 ... 预处理器定义中。

__declspec(dllimport)是 Microsoft 对 C++ 的特定扩展。Microsoft 拥有出色的在线文档。

于 2013-02-20T13:16:02.543 回答
2

在 DLL 项目中,#defineCOMPILING_DLL. 因为这不会为任何其他项目设置(特别是如果您将其命名为比 更好的名称COMPILING_DLL),那么该#if指令将正常工作。

于 2013-02-20T13:14:23.337 回答
2

您(在理想情况下实际上是 Visual Studio)在COMPILING_DLL构建 DLL 时将 定义为编译器的参数。因此,它将默认为__declspec(dllexport). 另一方面,当您使用 DLL 的头文件时,您没有定义它,因此DLLEXPORT默认情况下将评估为__declspec(dllimport).

于 2013-02-20T13:16:05.803 回答
1

您不能在头文件中以这种方式定义函数体。它被__declspec(dllimport) 禁止。该说明符只能在函数声明中指定,不能在定义中指定。

您必须将函数体移动到源文件。

在头文件中:

extern DLLEXPORT void test2();

在 .cpp 文件中:

void test2()
{
   // ...
}

正如人们所说,不要忘记将 COMPILING_DLL 添加到项目预处理器定义中。

于 2013-02-20T13:45:05.827 回答
1

实际上,真正的问题是预处理器指令。您应该使用#ifdef而不是#if测试变量是否真正定义(我们不关心定义的值或是否存在)。

注意:我知道这个线程已有 1 年的历史,但它仍然可能对将来遇到此问题的人有用。

于 2014-01-23T17:18:48.710 回答
1

如果您使用 CMake 生成构建配置,您应该能够以<projectname>_EXPORTS您想要使用的方式使用宏COMPILING_DLL,其中projectname使用 CMake 命令定义project(projectname)

<target_name>_EXPORTS检测到共享库编译时定义预处理器宏。

来源

我进行了测试,它使用 Ninja 生成器和 Visual Studio 2015 Express 的编译器 MSVC 在 Windows 上运行。

相关:CMake 添加 -Dlibname_EXPORTS 编译定义

于 2019-02-15T13:18:00.350 回答