Sharing an enum from C#, C++/CLI, and C++

前端 未结 3 1991
甜味超标
甜味超标 2020-12-08 20:34

I have a library that consists of three parts. First is native C++, which provides the actual functionality. Second is a C++/CLI wrapper/adaptor for the C++ library, to si

相关标签:
3条回答
  • 2020-12-08 20:54

    Even if you include the C# enum in your native C++ (as suggested in your first link), both enums are not "the same", the C++ enum is nothing but a list of named integers, while the C# enum is derived from Enum. As a consequence, you get a collision in C++/CLI when trying to use them both.

    A possible solution is to use the preprocessor so that your C++/CLI assembly sees both enums in different namespaces:

    // shared_enum.h
    
    #undef ENUMKEYWORD
    #undef ENUMNAMESPACE
    
    #ifdef MANAGED
    #define ENUMKEYWORD public enum class
    #define ENUMNAMESPACE EnumShareManaged
    #else
    #define ENUMKEYWORD enum
    #define ENUMNAMESPACE EnumShare
    #endif
    
    namespace ENUMNAMESPACE
    {
        ENUMKEYWORD MyEnum
        {
            a = 1,
            b = 2,
            c = 3,
        };
    }
    

    In your C++/CLI code, make an inclusion like that:

    #undef MANAGED
    #include "shared_enum.h"
    #define MANAGED
    #include "shared_enum.h"
    

    This gives you the availability to distinguish between those two kind of enums EnumShare::MyEnum or EnumShareManaged::MyEnum in your C++/CLI code.

    EDIT: just found this SO post showing the correct way to cast between unmanaged and managed enums, this surely will work here, too. For example, in the C++/CLI, the transition from managed to unmanaged enum can be done like this:

    void MyWrapperClass::MyWrapperFunction(EnumShareManaged::MyEnum mx)
    {
        EnumShare::MyEnum nx = static_cast<EnumShare::MyEnum>(mx);
        // call a native function "func"
        func(nx);
    }
    
    0 讨论(0)
  • 2020-12-08 21:01

    Just put your #include "Enum.cs" directive inside an outer namespace to resolve the naming collision.

    EDIT: A variation suggested by Brent is to use #define to substitute one of the namespaces (or even the enum name itself) declared in the .cs file. This also avoids the naming collision, without making the namespace hierarchy deeper.

    0 讨论(0)
  • 2020-12-08 21:09

    Consider writing code generator program, which reads native h-file file with enumerations and generates another h-file, converting enum to C++/CLI enum class. Such code generator can be used in C++/CLI project on the Custom Build Step, producing required CLI enumerations.

    I use this approach to generate native wrapper classes to get Enum::GetNames and Enum::GetName functions in unmanaged C++.

    0 讨论(0)
提交回复
热议问题