C++/CLI managed Enum appears empty in CSharp

Collapse
This topic is closed.
X
X
 
  • Time
  • Show
Clear All
new posts
  • Cmtk Software

    #1

    C++/CLI managed Enum appears empty in CSharp


    I'm trying to define an enum which will be used from unmanaged c++, C++/CLI
    managed c++ and from C#.
    I defined the following enum in a VS dll project set to be compiled with the
    /clr switch:

    public enum Days
    {
    Sunday
    };

    After building the project, I added the created DLL as a reference in a C#
    project.
    Trying to use this enum from inside the C# project, Days itself was visible
    but none of its fields (Sunday) existed (Days was empty).
    For verification, I right clicked on the DLL reference and selected "View in
    Object Browser". Again, "Days" existed but was empty - Sunday simply wasn't
    there.
    I tried creating an enum class in the CLI managed c++ project:
    public enum class Days
    {
    Sunday
    };

    And both the enum itself and its fields were visible and usable from C#.
    However this cannot be my solution because the "enum class" cannot be used
    from unmanaged c++.

    The enum class reference on MSDN
    (http://msdn2.microsoft.com/en-us/lib...49(VS.80).aspx) states:
    "A named, standard enum compiled with /clr will be visible in the assembly
    as a managed enum, and can be consumed by any other managed compiler."

    How can I make Sunday accessible from C#?

    Thanks in advance.
  • Marcus Heege

    #2
    Re: C++/CLI managed Enum appears empty in CSharp

    Use public enum class instead of public enum.

    Marcus

    "Cmtk Software" <CmtkSoftware@n ewsgroup.nospam wrote in message
    news:1A26493D-169B-422F-A7A0-416A3E17ADEA@mi crosoft.com...
    >
    I'm trying to define an enum which will be used from unmanaged c++,
    C++/CLI
    managed c++ and from C#.
    I defined the following enum in a VS dll project set to be compiled with
    the
    /clr switch:
    >
    public enum Days
    {
    Sunday
    };
    >
    After building the project, I added the created DLL as a reference in a C#
    project.
    Trying to use this enum from inside the C# project, Days itself was
    visible
    but none of its fields (Sunday) existed (Days was empty).
    For verification, I right clicked on the DLL reference and selected "View
    in
    Object Browser". Again, "Days" existed but was empty - Sunday simply
    wasn't
    there.
    I tried creating an enum class in the CLI managed c++ project:
    public enum class Days
    {
    Sunday
    };
    >
    And both the enum itself and its fields were visible and usable from C#.
    However this cannot be my solution because the "enum class" cannot be used
    from unmanaged c++.
    >
    The enum class reference on MSDN
    (http://msdn2.microsoft.com/en-us/lib...49(VS.80).aspx) states:
    "A named, standard enum compiled with /clr will be visible in the assembly
    as a managed enum, and can be consumed by any other managed compiler."
    >
    How can I make Sunday accessible from C#?
    >
    Thanks in advance.

    Comment

    • Bruno van Dooren [MVP VC++]

      #3
      Re: C++/CLI managed Enum appears empty in CSharp

      Use public enum class instead of public enum.

      Hi Marcus,

      He wanted to use an unmanaged enum because that way it could be used both in
      managed and unmanaged code.
      According to MSDN an unmanaged enum compiled with /clr should be inserted
      into the assembly as a managed enum.
      see
      http://msdn2.microsoft.com/en-us/lib...49(VS.80).aspx

      --
      Kind regards,
      Bruno.
      bruno_nos_pam_v an_dooren@hotma il.com
      Remove only "_nos_pam"

      Comment

      • Cmtk Software

        #4
        Re: C++/CLI managed Enum appears empty in CSharp

        Hi Bruno,

        I read the MSDN page you mentioned (I also referenced it in my post). The
        problem is, as I mentioned in my question, that from inside C#, the enum
        seems empty.
        This code in CLI:

        public enum Days
        {
        Sunday
        };

        Producing the following metadata:

        public enum Days
        {
        }

        - An empty enum. I know this contradicts what is written in the MSDN page
        you mentioned.
        Can you please explain why this happens.
        "Bruno van Dooren [MVP VC++]" wrote:
        Use public enum class instead of public enum.
        >
        Hi Marcus,
        >
        He wanted to use an unmanaged enum because that way it could be used both in
        managed and unmanaged code.
        According to MSDN an unmanaged enum compiled with /clr should be inserted
        into the assembly as a managed enum.
        see
        http://msdn2.microsoft.com/en-us/lib...49(VS.80).aspx
        >
        --
        Kind regards,
        Bruno.
        bruno_nos_pam_v an_dooren@hotma il.com
        Remove only "_nos_pam"
        >

        Comment

        • Marcus Heege

          #5
          Re: C++/CLI managed Enum appears empty in CSharp

          >Hi Marcus,
          >>
          >He wanted to use an unmanaged enum because that way it could be used both
          >in
          >managed and unmanaged code.
          >According to MSDN an unmanaged enum compiled with /clr should be inserted
          >into the assembly as a managed enum.
          >see
          >http://msdn2.microsoft.com/en-us/lib...49(VS.80).aspx
          >>
          >--
          >Kind regards,
          > Bruno.
          > bruno_nos_pam_v an_dooren@hotma il.com
          > Remove only "_nos_pam"
          OOps It seems I read that question too quick.

          Here is some background info:

          For native types like structs, classes, enums, and unions, the C++/CLI
          compiler generates managed wrapper types as soon as these are used in
          managed code. However, these wrapper types are more primitive as one might
          think. For structs, classes, and unions, they are value types without any
          fields. Only the native size of the struct, class, or union is specified in
          the metadata. For enums, a managed enum is created, however, it only
          contains the standard field to store the value.

          Here is the solution that I would suggest:

          To see the enum values on both sides, you should define two enums:

          In your assembly a public managed enum:
          public enum class E
          { a, b, c };

          In the header that is included in C++ projects, an equivalent native enum:
          #ifndef _MANAGED
          enum E
          { a, b, c };
          #else
          #using "yourAssembly.d ll"
          #endif

          If the header is included in a file compiled with /clr:* or, the managed
          enum will be visible, because
          #using "yourAssembly.d ll"
          will be compiled with your code.
          If the header is included in a file complied without /clr:*, the native enum
          will be defined.



          Comment

          • Cmtk Software

            #6
            Re: C++/CLI managed Enum appears empty in CSharp

            Hi Marcus,

            Thanks alot for all the background information!
            Your solution creates a double definition of the enum (This enum is defined
            in two different places) and so, might create a problem in the future when
            someone changes one enum and doesn't know he should also change the other one
            accordingly.
            This's why I wanted all factors to use the same enum definition.

            The solution I used temporarly is:
            enum Days
            {
            Day_Sunday,
            Day_Monday
            };

            public enum class ManagedDays
            {
            Sunday = Day_Sunday,
            Monday = Day_Monday,
            };

            This way values of the items in both enums corresponds.
            I'll keep looking for a way to define only one enum which will be usable by
            all. If I do find such a way, I'll post it in this thread.

            Again, thanks for your help!

            "Marcus Heege" wrote:
            Hi Marcus,
            >
            He wanted to use an unmanaged enum because that way it could be used both
            in
            managed and unmanaged code.
            According to MSDN an unmanaged enum compiled with /clr should be inserted
            into the assembly as a managed enum.
            see
            http://msdn2.microsoft.com/en-us/lib...49(VS.80).aspx
            >
            --
            Kind regards,
            Bruno.
            bruno_nos_pam_v an_dooren@hotma il.com
            Remove only "_nos_pam"
            >
            OOps It seems I read that question too quick.
            >
            Here is some background info:
            >
            For native types like structs, classes, enums, and unions, the C++/CLI
            compiler generates managed wrapper types as soon as these are used in
            managed code. However, these wrapper types are more primitive as one might
            think. For structs, classes, and unions, they are value types without any
            fields. Only the native size of the struct, class, or union is specified in
            the metadata. For enums, a managed enum is created, however, it only
            contains the standard field to store the value.
            >
            Here is the solution that I would suggest:
            >
            To see the enum values on both sides, you should define two enums:
            >
            In your assembly a public managed enum:
            public enum class E
            { a, b, c };
            >
            In the header that is included in C++ projects, an equivalent native enum:
            #ifndef _MANAGED
            enum E
            { a, b, c };
            #else
            #using "yourAssembly.d ll"
            #endif
            >
            If the header is included in a file compiled with /clr:* or, the managed
            enum will be visible, because
            #using "yourAssembly.d ll"
            will be compiled with your code.
            If the header is included in a file complied without /clr:*, the native enum
            will be defined.
            >
            >
            >
            >

            Comment

            • Marcus Heege

              #7
              Re: C++/CLI managed Enum appears empty in CSharp

              I guess I have to agree that there is no good solution to this problem ...

              Marcus

              "Cmtk Software" <CmtkSoftware@n ewsgroup.nospam wrote in message
              news:B9949CFD-452C-4230-B513-F16AF8B7358D@mi crosoft.com...
              Hi Marcus,
              >
              Thanks alot for all the background information!
              Your solution creates a double definition of the enum (This enum is
              defined
              in two different places) and so, might create a problem in the future when
              someone changes one enum and doesn't know he should also change the other
              one
              accordingly.
              This's why I wanted all factors to use the same enum definition.
              >
              The solution I used temporarly is:
              enum Days
              {
              Day_Sunday,
              Day_Monday
              };
              >
              public enum class ManagedDays
              {
              Sunday = Day_Sunday,
              Monday = Day_Monday,
              };
              >
              This way values of the items in both enums corresponds.
              I'll keep looking for a way to define only one enum which will be usable
              by
              all. If I do find such a way, I'll post it in this thread.
              >
              Again, thanks for your help!
              >
              "Marcus Heege" wrote:
              >
              >Hi Marcus,
              >>
              >He wanted to use an unmanaged enum because that way it could be used
              >both
              >in
              >managed and unmanaged code.
              >According to MSDN an unmanaged enum compiled with /clr should be
              >inserted
              >into the assembly as a managed enum.
              >see
              >http://msdn2.microsoft.com/en-us/lib...49(VS.80).aspx
              >>
              >--
              >Kind regards,
              > Bruno.
              > bruno_nos_pam_v an_dooren@hotma il.com
              > Remove only "_nos_pam"
              >>
              >OOps It seems I read that question too quick.
              >>
              >Here is some background info:
              >>
              >For native types like structs, classes, enums, and unions, the C++/CLI
              >compiler generates managed wrapper types as soon as these are used in
              >managed code. However, these wrapper types are more primitive as one
              >might
              >think. For structs, classes, and unions, they are value types without any
              >fields. Only the native size of the struct, class, or union is specified
              >in
              >the metadata. For enums, a managed enum is created, however, it only
              >contains the standard field to store the value.
              >>
              >Here is the solution that I would suggest:
              >>
              >To see the enum values on both sides, you should define two enums:
              >>
              >In your assembly a public managed enum:
              >public enum class E
              >{ a, b, c };
              >>
              >In the header that is included in C++ projects, an equivalent native
              >enum:
              >#ifndef _MANAGED
              >enum E
              >{ a, b, c };
              >#else
              >#using "yourAssembly.d ll"
              >#endif
              >>
              >If the header is included in a file compiled with /clr:* or, the managed
              >enum will be visible, because
              > #using "yourAssembly.d ll"
              >will be compiled with your code.
              >If the header is included in a file complied without /clr:*, the native
              >enum
              >will be defined.
              >>
              >>
              >>
              >>

              Comment

              • Marcus Heege

                #8
                Re: C++/CLI managed Enum appears empty in CSharp

                "Marcus Heege" <nospam@heege.n etwrote in message
                news:eo1oxfuDHH A.4280@TK2MSFTN GP04.phx.gbl...
                >I guess I have to agree that there is no good solution to this problem ...
                >
                Marcus
                >
                One last attempt. How about this:

                [assembly: ComVisible(fals e)] // ensure that all other types do not end up
                in the COM type library

                [ComVisible(true )] // ensure that the enum type ends up
                in the COM type library
                public enum class Days
                {
                Monday, // ...
                };

                Managed clients can use this by just referencing the assembly. Native
                clients can use this enum via #import.



                Comment

                • Ben Voigt

                  #9
                  Re: C++/CLI managed Enum appears empty in CSharp


                  "Marcus Heege" <nospam@heege.n etwrote in message
                  news:eo1oxfuDHH A.4280@TK2MSFTN GP04.phx.gbl...
                  >I guess I have to agree that there is no good solution to this problem ...
                  #include the same header file twice, with different #defines:

                  #define ENUMDECL enum class
                  #include "enumdef.h"
                  #undef ENUMDECL

                  #define ENUMDECL enum
                  #include "enumdef.h"
                  #undef ENUMDECL
                  >
                  Marcus
                  >
                  "Cmtk Software" <CmtkSoftware@n ewsgroup.nospam wrote in message
                  news:B9949CFD-452C-4230-B513-F16AF8B7358D@mi crosoft.com...
                  >Hi Marcus,
                  >>
                  >Thanks alot for all the background information!
                  >Your solution creates a double definition of the enum (This enum is
                  >defined
                  >in two different places) and so, might create a problem in the future
                  >when
                  >someone changes one enum and doesn't know he should also change the other
                  >one
                  >accordingly.
                  >This's why I wanted all factors to use the same enum definition.
                  >>
                  >The solution I used temporarly is:
                  >enum Days
                  >{
                  > Day_Sunday,
                  > Day_Monday
                  >};
                  >>
                  >public enum class ManagedDays
                  >{
                  > Sunday = Day_Sunday,
                  > Monday = Day_Monday,
                  >};
                  >>
                  >This way values of the items in both enums corresponds.
                  >I'll keep looking for a way to define only one enum which will be usable
                  >by
                  >all. If I do find such a way, I'll post it in this thread.
                  >>
                  >Again, thanks for your help!
                  >>
                  >"Marcus Heege" wrote:
                  >>
                  >>Hi Marcus,
                  >>>
                  >>He wanted to use an unmanaged enum because that way it could be used
                  >>both
                  >>in
                  >>managed and unmanaged code.
                  >>According to MSDN an unmanaged enum compiled with /clr should be
                  >>inserted
                  >>into the assembly as a managed enum.
                  >>see
                  >>http://msdn2.microsoft.com/en-us/lib...49(VS.80).aspx
                  >>>
                  >>--
                  >>Kind regards,
                  >> Bruno.
                  >> bruno_nos_pam_v an_dooren@hotma il.com
                  >> Remove only "_nos_pam"
                  >>>
                  >>OOps It seems I read that question too quick.
                  >>>
                  >>Here is some background info:
                  >>>
                  >>For native types like structs, classes, enums, and unions, the C++/CLI
                  >>compiler generates managed wrapper types as soon as these are used in
                  >>managed code. However, these wrapper types are more primitive as one
                  >>might
                  >>think. For structs, classes, and unions, they are value types without
                  >>any
                  >>fields. Only the native size of the struct, class, or union is specified
                  >>in
                  >>the metadata. For enums, a managed enum is created, however, it only
                  >>contains the standard field to store the value.
                  >>>
                  >>Here is the solution that I would suggest:
                  >>>
                  >>To see the enum values on both sides, you should define two enums:
                  >>>
                  >>In your assembly a public managed enum:
                  >>public enum class E
                  >>{ a, b, c };
                  >>>
                  >>In the header that is included in C++ projects, an equivalent native
                  >>enum:
                  >>#ifndef _MANAGED
                  >>enum E
                  >>{ a, b, c };
                  >>#else
                  >>#using "yourAssembly.d ll"
                  >>#endif
                  >>>
                  >>If the header is included in a file compiled with /clr:* or, the managed
                  >>enum will be visible, because
                  >> #using "yourAssembly.d ll"
                  >>will be compiled with your code.
                  >>If the header is included in a file complied without /clr:*, the native
                  >>enum
                  >>will be defined.
                  >>>
                  >>>
                  >>>
                  >>>
                  >
                  >

                  Comment

                  • Marcus Heege

                    #10
                    Re: C++/CLI managed Enum appears empty in CSharp

                    "Ben Voigt" <rbv@nospam.nos pamwrote in message
                    news:umnYGw9DHH A.992@TK2MSFTNG P03.phx.gbl...
                    >
                    "Marcus Heege" <nospam@heege.n etwrote in message
                    news:eo1oxfuDHH A.4280@TK2MSFTN GP04.phx.gbl...
                    >>I guess I have to agree that there is no good solution to this problem ...
                    >
                    #include the same header file twice, with different #defines:
                    >
                    #define ENUMDECL enum class
                    #include "enumdef.h"
                    #undef ENUMDECL
                    >
                    #define ENUMDECL enum
                    #include "enumdef.h"
                    #undef ENUMDECL
                    The problem with this approach is that it break the rules of managed type
                    identity. Including this header in two different projects would produce two
                    different managed enums.

                    Marcus


                    Comment

                    • Ben Voigt

                      #11
                      Re: C++/CLI managed Enum appears empty in CSharp


                      "Marcus Heege" <nospam@heege.n etwrote in message
                      news:eKxAXN$DHH A.348@TK2MSFTNG P06.phx.gbl...
                      "Ben Voigt" <rbv@nospam.nos pamwrote in message
                      news:umnYGw9DHH A.992@TK2MSFTNG P03.phx.gbl...
                      >>
                      >"Marcus Heege" <nospam@heege.n etwrote in message
                      >news:eo1oxfuDH HA.4280@TK2MSFT NGP04.phx.gbl.. .
                      >>>I guess I have to agree that there is no good solution to this problem
                      >>>...
                      >>
                      >#include the same header file twice, with different #defines:
                      >>
                      >#define ENUMDECL enum class
                      >#include "enumdef.h"
                      >#undef ENUMDECL
                      >>
                      >#define ENUMDECL enum
                      >#include "enumdef.h"
                      >#undef ENUMDECL
                      >
                      The problem with this approach is that it break the rules of managed type
                      identity. Including this header in two different projects would produce
                      two different managed enums.
                      The header file is for the library and native clients (with appropriate
                      preprocessor conditionals to remove the C++/CLI definitions when used from
                      standard C++), while managed clients don't use #include at all but #import.
                      >
                      Marcus
                      >

                      Comment

                      • =?Utf-8?B?Q210ayBTb2Z0d2FyZQ==?=

                        #12
                        Re: C++/CLI managed Enum appears empty in CSharp

                        Dear Ben,

                        My solution includes a managed project (compiled with /clr), which is linked
                        to a DLL.
                        I have two classes in this DLL: a native worker and its managed (ref) wrapper.
                        This's why I need an enum which can be used by C# (which references this
                        library), managed c++ and native c++.
                        I already tried your solution (to include the header with the enum
                        definition twice). It causes a linkage error because both the native enum and
                        the managed enum are exported and visible for the DLL clients and therefore
                        cannot have the same name.
                        The problem is that the native enum is exported empty and its fields are not
                        exported.

                        I'm still battling this one and the temporary solution I mentioned a few
                        posts back is becoming more and more permanent...

                        Any suggestion will be appreciated.

                        "Ben Voigt" wrote:
                        >
                        "Marcus Heege" <nospam@heege.n etwrote in message
                        news:eKxAXN$DHH A.348@TK2MSFTNG P06.phx.gbl...
                        "Ben Voigt" <rbv@nospam.nos pamwrote in message
                        news:umnYGw9DHH A.992@TK2MSFTNG P03.phx.gbl...
                        >
                        "Marcus Heege" <nospam@heege.n etwrote in message
                        news:eo1oxfuDHH A.4280@TK2MSFTN GP04.phx.gbl...
                        >>I guess I have to agree that there is no good solution to this problem
                        >>...
                        >
                        #include the same header file twice, with different #defines:
                        >
                        #define ENUMDECL enum class
                        #include "enumdef.h"
                        #undef ENUMDECL
                        >
                        #define ENUMDECL enum
                        #include "enumdef.h"
                        #undef ENUMDECL
                        The problem with this approach is that it break the rules of managed type
                        identity. Including this header in two different projects would produce
                        two different managed enums.
                        >
                        The header file is for the library and native clients (with appropriate
                        preprocessor conditionals to remove the C++/CLI definitions when used from
                        standard C++), while managed clients don't use #include at all but #import.
                        >

                        Marcus
                        >
                        >
                        >

                        Comment

                        • Ben Voigt

                          #13
                          Re: C++/CLI managed Enum appears empty in CSharp


                          "Cmtk Software" <CmtkSoftware@n ewsgroup.nospam wrote in message
                          news:BE0F9D7F-7ADC-4264-8335-F611A4552744@mi crosoft.com...
                          Dear Ben,
                          >
                          My solution includes a managed project (compiled with /clr), which is
                          linked
                          to a DLL.
                          I have two classes in this DLL: a native worker and its managed (ref)
                          wrapper.
                          This's why I need an enum which can be used by C# (which references this
                          library), managed c++ and native c++.
                          I already tried your solution (to include the header with the enum
                          definition twice). It causes a linkage error because both the native enum
                          and
                          the managed enum are exported and visible for the DLL clients and
                          therefore
                          cannot have the same name.
                          Can you just give them different names, via a second #define?

                          Or else put them inside different namespaces?

                          namespace dotnet {
                          #define ENUMDECL enum class
                          #include "enumdef.h"
                          #undef ENUMDECL
                          }
                          namespace native {
                          #define ENUMDECL enum
                          #include "enumdef.h"
                          #undef ENUMDECL
                          }
                          The problem is that the native enum is exported empty and its fields are
                          not
                          exported.
                          >
                          I'm still battling this one and the temporary solution I mentioned a few
                          posts back is becoming more and more permanent...
                          >
                          Any suggestion will be appreciated.
                          >
                          "Ben Voigt" wrote:
                          >
                          >>
                          >"Marcus Heege" <nospam@heege.n etwrote in message
                          >news:eKxAXN$DH HA.348@TK2MSFTN GP06.phx.gbl...
                          "Ben Voigt" <rbv@nospam.nos pamwrote in message
                          news:umnYGw9DHH A.992@TK2MSFTNG P03.phx.gbl...
                          >>
                          >"Marcus Heege" <nospam@heege.n etwrote in message
                          >news:eo1oxfuDH HA.4280@TK2MSFT NGP04.phx.gbl.. .
                          >>>I guess I have to agree that there is no good solution to this problem
                          >>>...
                          >>
                          >#include the same header file twice, with different #defines:
                          >>
                          >#define ENUMDECL enum class
                          >#include "enumdef.h"
                          >#undef ENUMDECL
                          >>
                          >#define ENUMDECL enum
                          >#include "enumdef.h"
                          >#undef ENUMDECL
                          >
                          The problem with this approach is that it break the rules of managed
                          type
                          identity. Including this header in two different projects would produce
                          two different managed enums.
                          >>
                          >The header file is for the library and native clients (with appropriate
                          >preprocessor conditionals to remove the C++/CLI definitions when used
                          >from
                          >standard C++), while managed clients don't use #include at all but
                          >#import.
                          >>
                          >
                          Marcus
                          >
                          >>
                          >>
                          >>

                          Comment

                          Working...