简体   繁体   English

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

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

I am trying to make a C++/CLI wrapper for my native C++ project so that I can use it in C#. 我正在尝试为本机C ++项目制作一个C ++ / CLI包装程序,以便可以在C#中使用它。 So far I've wrapped the classes and functions that I need, but I've been trying to find a way to do the same for Enums without having to copy and paste the code to the wrapper. 到目前为止,我已经包装了所需的类和函数,但是我一直在尝试寻找一种方法来对Enums执行相同的操作,而不必将代码复制并粘贴到包装器中。

I've tried looking up ways to wrap enums, but it seems that there's no way to use the enums that are from the native C++ code without having to cast/rewrite the code in the wrapper layer. 我尝试过寻找包装枚举的方法,但是似乎没有办法使用本地C ++代码中的枚举,而不必在包装层中强制转换/重写代码。 So I found a solution where you use preprocessor directives and include the enums twice into the wrapper, but it seems not to be working for some reason. 因此,我找到了一个解决方案,其中使用预处理器指令并将枚举两次包含在包装中,但是由于某种原因,它似乎无法正常工作。

Native Code (Enums.h) 本机代码(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,
    }
}

Managed Code (Wrapper.h) 托管代码(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# Code (Main.cs) C#代码(Main.cs)

using managed; //managed project added as reference

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

I expect to be able to use managed::numbers in the managed project alongside native::numbers. 我希望能够在托管项目中与native :: numbers一起使用managed :: numbers。 I also expect to be able to use the numbers enum in C#. 我也希望能够在C#中使用数字枚举。 However, visual studio has not been able to do this. 但是,Visual Studio无法做到这一点。 I've tried rearranging the includes as well but that doesn't seem to work. 我也尝试过重新整理包含内容,但这似乎行不通。

I made a test file in the managed class that includes Enums.h, but not Native.h: 我在托管类中创建了一个测试文件,其中包括Enums.h,但不包括Native.h:

TestFile.h 测试文件

#ifndef TESTFILE_H
#define TESTFILE_H

#define MANAGED
#include "Enums.h"

namespace managed
{
    managed::numbers num = managed::numbers::ONE; //Works 
}

#endif //!TESTFILE_H

This works, but I also need to be able to include Native.h and use the enums from there as well 这可行,但是我还需要能够包含Native.h并从那里使用枚举

Edit: Using @robthebloke answer, What I got to work is in Enums.h to do: 编辑:使用@robthebloke答案,我要做的工作是在Enums.h中执行:

#pragma once

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

And then in Wrapper.h: 然后在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

Is there any way to just use one file instead of having to use EnumsImpl.h? 有什么方法可以只使用一个文件,而不必使用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 

Enums.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

An Alternative... 替代...

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

DefEnum(dave, enum class);

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM