如何使用预处理器指令包含两次具有不同代码的文件?

How to use preprocessor directives to include file twice with different code?

本文关键字:代码 文件 预处理 何使用 处理器 指令 包含两      更新时间:2023-10-16

我正在尝试为我的本机C++项目制作一个 C++/CLI 包装器,以便我可以在 C# 中使用它。到目前为止,我已经包装了我需要的类和函数,但我一直在尝试找到一种方法来对 Enums 做同样的事情,而无需将代码复制并粘贴到包装器中。

我尝试查找包装枚举的方法,但似乎没有办法使用来自本机C++代码的枚举,而无需在包装层中转换/重写代码。所以我找到了一个解决方案,您可以使用预处理器指令并将枚举包含在包装器中两次,但由于某种原因它似乎不起作用。

本机代码 (Enums.h)

#pragma once
#if defined MANAGED && !defined ENUMS_MANAGED_H
#define ENUMS_MANAGED_H
#define NAMESPACE managed
#define ENUM public enum class
#elif !defined MANAGED && !defined ENUMS_NATIVE_H
#define ENUMS_NATIVE_H
#define NAMESPACE native
#define ENUM enum class
#endif
namespace NAMESPACE
{
ENUM numbers
{
ONE = 1,
TWO = 2,
}
}

托管代码 (Wrapper.h)

#pragma once
#ifndef WRAPPER_H
#define WRAPPER_H
#include "Native.h" //Other native code which also includes Enums.h
#define MANAGED
#include "Enums.h"
namespace managed
{
managed::numbers num = managed::numbers::ONE; //managed does not contain 'numbers'
}
#endif //!WRAPPER_H

C# 代码(主.cs)

using managed; //managed project added as reference
static void main(String[] args)
{
Console.WriteLine((int) numbers.ONE); //managed does not contain 'numbers'
}

我希望能够在托管项目中与本机::数字一起使用托管::数字。我还希望能够在 C# 中使用数字枚举。但是,Visual Studio无法做到这一点。我也尝试重新排列包含,但这似乎不起作用。

我在托管类中创建了一个测试文件,其中包含 Enums.h,但不包含 Native.h:

测试文件.h

#ifndef TESTFILE_H
#define TESTFILE_H
#define MANAGED
#include "Enums.h"
namespace managed
{
managed::numbers num = managed::numbers::ONE; //Works 
}
#endif //!TESTFILE_H

这有效,但我还需要能够包含 Native.h 并从那里使用枚举

编辑: 使用@robthebloke答案, 我的工作是在 Enums.h 中要做的:

#pragma once
// to disable error in EnumsImpl.h
#define BUILDING_ENUMS
#include "EnumsImpl.h"
#undef BUILDING_ENUMS

然后在 Wrapper.h 中:

#pragma once
#ifndef WRAPPER_H
#define WRAPPER_H
#include "Native.h"
#define BUILDING_ENUMS
#define MANAGED
#include "EnumsImpl.h"
#undef MANAGED
#undef BUILDING_ENUMS
#endif

有没有办法只使用一个文件而不必使用 EnumsImpl.h?

EnumsImpl.h

// guard against incorrect usage. 
#if !defined(BUILDING_ENUMS)
#error "Do not include this file directly, include Enums.h instead"
#endif
// choose macros for below
#if defined MANAGED
#define NAMESPACE managed
#define ENUM public enum class
#elif !defined MANAGED
#define NAMESPACE native
#define ENUM enum class
#endif
namespace NAMESPACE
{
ENUM numbers
{
ONE = 1,
TWO = 2,
}
}
#undef NAMESPACE 
#undef ENUM 

枚举.h

#pragma once
// to disable error in EnumsImpl.h
#define BUILDING_ENUMS
// unmanaged
#include "EnumsImpl.h"
// managed
#define MANAGED
#include "EnumsImpl.h"
// remove temp defines
#undef MANAGED
#undef BUILDING_ENUMS

另一种选择...

#define DefEnum(NAMESPACE, ENUM) 
namespace NAMESPACE 
{ 
ENUM numbers 
{ 
ONE = 1, 
TWO = 2, 
}; 
}
DefEnum(dave, enum class);