检查预处理器中的__declspec宏

时间:2018-01-19 22:04:44

标签: c++ c-preprocessor

如果我将SOME_MACRO定义为__declspec(dllimport)__declspec(dllexport),是否有办法在编译时检查哪一个正在使用?

即。像这样的东西:

#if SOME_MACRO == __declspec(dllimport)
// do something
#else
// do something else
#endif

UPD。 看看我得到的答案,我想我应该更具体地说明为什么我需要这个。

我正在尝试编译一个相当大的第三方库,它的代码的大多数部分都包含一个声明为dllexport的函数。然而,有一个组件是dllimport

我需要为dllimport案例略微修改声明。两个声明之间的切换不是很简单,它是跨越几个文件的相当深的#ifdef指令树的结果。原则上我可以从这些说明中挖掘出这些信息,但为了确保我做得正确,我必须尝试在几种不同的配置下编译整个库(每个编译花费几个小时)。

另一方面,如果有一种简单的方法可以检查他们的SOME_MACRO是否被评估为导入或导出,我可以在一个小程序上快速安全地将其测试到库中。

2 个答案:

答案 0 :(得分:2)

你不能使用

#if SOME_MACRO == __declspec(dllimport)

__declspec(dllimport)不是预处理程序表达式的有效标记。

您最好的选择是使用另一个预处理器宏,例如:

// Are we building the DLL?
#if defined(BUILD_DLL)
   // Yes, we are.
   #define SOME_MACRO __declspec(dllexport)
#else
   // No. We are using the DLL
   #define SOME_MACRO __declspec(dllimport)
#endif

现在,您可以使用:

#if defined(BUILD_DLL)

根据您是在构建DLL还是使用DLL来包含条件代码。

实际上,最终会涉及更多内容。

  1. 大多数项目都有多个DLL。 BUILD_DLL不起作用。对于您构建的每个DLL,您将需要BUILD_xxx_DLL。假设你有两个DLL,实用程序和核心。以及依赖于两者的应用程序。

  2. 您可能还需要创建一个静态库。

  3. 在实用程序库的每个公共.h文件中都需要类似以下内容。

    #if defined(BUILD_UTILITY_STATIC)
       #define UTLIITY_EXPORT
    #elif defined(BUILD_UTILITY_DLL)
       #define UTLIITY_EXPORT__declspec(dllexport)
    #else
       #define UTLIITY_EXPORT__declspec(dllimport)
    #endif
    

    当然,您不希望在许多.h文件中重复相同的代码。您将创建一个包含上述内容的.h文件以及所有其他.h文件中的#include

    构建utility.dll时,您需要定义BUILD_UTILITY_DLL并保持BUILD_UTILITY_STATIC未定义。

    在构建utllity.lib(静态库)时,您需要定义BUILD_UTILITY_STATIC并保持BUILD_UTILITY_DLL未定义。

    utility.dll的用户将离开BUILD_UTILITY_STATIC以及BUILD_UTILITY_DLL未定义。

    utility.lib(静态库)的用户需要定义BUILD_UTILITY_STATIC并保持BUILD_UTILITY_DLL未定义。

    您需要一个类似的core.dll和core.lib文件。

答案 1 :(得分:0)

宏由DLL创建者命名。

  • 您需要一个在导出或导入模式下工作的头文件。
  • 将使用C / C ++文件来创建程序,以构建DLL(导出)。
  • 其他C / C ++文件将用于调用DLL(导入函数)。

在构建实现​​文件中,在包含标头之前定义了您命名的宏。 e.g。

#define DLLNAME_BUILD_DLL
#include "dll_header.h"

在标题中,如果定义了宏,则将模式设置为export。使用DLL时,未定义宏并导入函数。