【问题标题】:Macro for dllexport/dllimport switchdllexport/dllimport 开关的宏
【发布时间】:2013-02-05 12:01:58
【问题描述】:
#if COMPILING_DLL
    #define DLLEXPORT __declspec(dllexport)
#else
    #define DLLEXPORT __declspec(dllimport)
#endif

我如何/在哪里定义 COMPILING_DLL

在这里看到: what does __declspec(dllimport) really mean?

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

【问题讨论】:

标签: c++ visual-studio-2010 visual-c++


【解决方案1】:

另一种选择:

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

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

属性 -> 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

【讨论】:

  • 很遗憾,在这个问题中复制的最有用的代码不在接受的答案中。至少你有它在这里给我们:)
  • @kayleeFrye_onDeck 该代码已存在问题。
  • 一旦我创建了一个 dll,仍然在另一个项目中使用它时,MYDLL_EXPORTS 保持设置,而这里应该取消设置。有人可以告诉我为什么会这样吗?
【解决方案2】:

定义COMPILING_DLL=1 的最佳位置是编译器的命令行。如果您使用 Visual Studio IDE,那么它位于 Project properties ... C/C++ ... Preprocessor ... Preprocessor Definitions 中。

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

【讨论】:

  • 我在预处理器定义中添加了 COMPILING_DLL,但它仍然在抱怨“错误 C2491:'test2':不允许定义 dllimport 函数”。这是没有意义的,因为 Visual Studio 现在甚至会灰显正确的那个。我添加了一个屏幕截图来说明这一点。
  • 您应该将该 COMPILING_DLL 添加到您的 DLL 项目的预处理器定义中。如果您将该头文件包含在该项目的预编译头文件中,请确保重新构建它。
【解决方案3】:

在 DLL 项目中,为COMPILING_DLL 添加一个#define(在头文件或项目属性中)。因为这不会为任何其他项目设置(特别是如果您将其命名为比COMPILING_DLL 更好的名称),那么#if 指令将正常工作。

【讨论】:

    【解决方案4】:

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

    【讨论】:

      【解决方案5】:

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

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

      在头文件中:

      extern DLLEXPORT void test2();
      

      在 .cpp 文件中:

      void test2()
      {
         // ...
      }
      

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

      【讨论】:

      • 您提到的编译器错误的来源(“错误C2491:'test2':不允许定义dllimport函数”)就是这个。但似乎可以通过在代码中显式使用#define COMPILING_DLL 而不是将其添加到: Project>properties>C/C++>Preprocessor>Preprocessor Definitions 来解决它
      【解决方案6】:

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

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

      【讨论】:

      • #if可以使用defined!defined,即#if defined SOMETHING || !defined SOMETHING_ELSE
      【解决方案7】:

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

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

      source

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

      相关:CMake adds -Dlibname_EXPORTS compile definition

      【讨论】:

        猜你喜欢
        • 2020-01-28
        • 1970-01-01
        • 2014-10-30
        • 2010-09-08
        • 2012-02-11
        • 1970-01-01
        • 2011-06-18
        • 1970-01-01
        相关资源
        最近更新 更多