Search code examples
c#c++-climanaged

Accessing Managed C++ Struct from C#


I have a managed C++ dll which contains the following

public value struct StructOuter
{
   public:
      int m_int_InStructOuter;
};

public ref class ClassContainingStruct : MyBase
{
   public:
          StructOuter^ m_strucOuter_InClassContainingStruct;
};

From a "C#" application, I am trying to access the following of the managed DLL: I receive the base class type object which i am converting to derived class object as follows.

ClassContainingStruct  ccs = (ClassContainingStruct)base;

When I try to print the contents of ccs, ccs.m_strucOuter_InClassContainingStruct is shown to me as ValueType by the Intellisense. Which is true, but if try to access the contents of ValueType, i.e. m_int_InStructOuter i.e. ccs.m_strucOuter_InClassContainingStruct.m_int_InStructOuter the following error is reported during compilation:

Error 1 'System.ValueType' does not contain a definition for 'm_int_InStructOuter' and no extension method 'm_int_InStructOuter' accepting a first argument of type 'System.ValueType' could be found (are you missing a using directive or an assembly reference?)

When I try go to definition on the C# application for the ClassContainingStruct class it is defined as follows(as per Metadata):

public class ClassContainingStruct : MyBase
{
        public ValueType m_strucOuter_InClassContainingStruct;
        ....
        [HandleProcessCorruptedStateExceptions]
        protected override void Dispose(bool value);
}
  1. Why it is mentioned as ValueType instead of StructOuter type
  2. Why i am getting a compilation error when I try to access ccs.m_strucOuter_InClassContainingStruct.m_int_InStructOuter

Solution

  • You did not declare it properly. Variables of a value types should not be declared with the ^ hat. That creates a value type value that is always boxed. Not something that C# understands, it has no equivalent syntax, it can only map it to System.ValueType. Only use the hat on reference types. You also forgot to declare the variable public. Fix:

    public ref class ClassContainingStruct : MyBase
    {
    public:
       StructOuter m_strucOuter_InClassContainingStruct;   // Note: no hat
    };
    

    As in C#, you ought to favor a property accessor instead.