如何控制不同项目中的#define 指令...?

How to control #define directive in different projects ...?

我的问题很直接。我只是想知道 C++ 中的 #define 指令是否可以控制不同的项目文件?精心设计,我有一个项目的头文件和一个cpp文件。文件代码如下:

MyHeader.h

#ifndef __MY_HEADER_H__

#include <cstring>
using namespace std;

#ifdef _HEADER_EXPORT_
#define HEADER_API __declspec(dllexport)
#else
#define HEADER_API __declspec(dllimport)
#endif

#ifdef __cplusplus
extern "C" {
#endif

class HEADER_API MyHeader
{
public:
    MyHeader();
    ~MyHeader();
#ifdef _HEADER_DISPLAY_
    void __cdecl ParseHeader();
#elif defined (_HEADER_RETURN_)
    string __cdecl ParseHeader();
#endif
};

#ifdef __cplusplus
}
#endif

#define __MY_HEADER_H__
#endif

MyHeader.cpp

#ifndef __MY_HEADER_H__
#include "MyHeader.h"
#endif

MyHeader::MyHeader() { }
MyHeader::~MyHeader() { }

#ifdef __cplusplus
extern "C" {
#endif

#ifdef _HEADER_DISPLAY_
    HEADER_API void __cdecl MyHeader::ParseHeader()
    {
        fputs(string("Displaying...").c_str(), stdout);
    }
#elif defined (_HEADER_RETURN_)
    HEADER_API string __cdecl MyHeader::ParseHeader()
    {
        string retVal("Returning...");
        return retVal;
    }
#endif

#ifdef __cplusplus
}
#endif

在另一个项目中 HeaderImpl.cpp 文件已使用以下代码实现。

HeaderImpl.cpp

#include "stdafx.h"

#define _HEADER_DISPLAY_ // To display the message

// #define _HEADER_RETURN_ // To return the message as string
#include "MyHeader.h"

int main(int argc, char* argv[])
{
    MyHeader header;
    MyHeader.ParseHeader(); // To display the message or to return the string
    return 0;
}

现在,我想知道如何使用 HeaderImpl.cpp 文件中的 #define 指令来控制 MyHeader.cpp 文件的 ParseHeader 方法?正如已经指出的那样,MyHeader.h 文件完全符合我的需要;即在声明 #define 指令时相应地控制 ParseHeader 方法。

你不能。每个 C++ 源文件都是独立编译的,其中的设置不会影响另一个。您必须在项目级别执行此操作。

一种方法是为这个宏的不同值设置不同的项目(和解决方案)配置。除了通常的 DebugRelease,您还可以添加 Debug-DisplayDebug-Return 等。然后您可以在项目设置中为每个配置定义宏。这将确保您 link 正确构建了您的库版本。


附带说明一下,您在代码中使用了非法名称。包含双下划线或以下划线后跟大写字母开头的名称是为编译器和标准库保留的。不允许用户代码出于自己的目的使用此类名称。

您通常可以在编译器的命令行上为所有编译单元提供#defines。 Visual studio 的 IIRC 类似于 /D_HEADER_DISPLAY_/D_HEADER_RETURN_

您的项目必须已经为 _HEADER_EXPORT_ 定义使用了类似的东西。

一个翻译单元中的预处理器定义无法远程影响另一个翻译单元。

尽管不是全部,但大多数编译器都接受它们作为编译参数(标志通常是 -D,或 /D 代表 VC++)。

在 Visual Studio 中,您可以在

下的项目设置中设置项目范围的预处理器定义
Configuration Properties -> C/C++ -> Preprocessor -> Preprocessor Definitions