none
Marshalling Struct ^ to void * RRS feed

  • Question

  • Hi everybody!

    I have such problem
    There is a code like this:

    using namespace System;
    using namespace System::Drawing;
    using namespace System::Runtime::InteropServices;
    
    // ...
    
    ref struct GRC
    {
         Bitmap ^ bt;
         // here I can have something else...
    
    };
    
    // ...
    
    GRC ^ gr = gcnew GRC;
    gc->bt = gcnew System::Drawing::Bitmap(100,100);
    
    // now I want to Convert it to void * 
    
    IntPtr p = AllocHGlobal( Marshal::SizeOf( gc ) );
    
    Marshal::StructureToPtr( gc, p, false );
    
    void * vp = p.ToPointer();
    
      
    It's very good compiling, but then it runs, I got message:

    An unhandled exception of type 'System.ArgumentException' occurred in myProject.exe
    Additional information: Type 'myProject.GRC' cannot be marshaled as an unmanaged structure; no meaningful size or offset can be computed.

    I understood that error appears in
    Marshal::SizeOf( gc )
    
    But, How can I correct it?

    http://msdn.microsoft.com/en-us/library/system.runtime.interopservices.marshal.structuretoptr.aspx
    Here examples on VB and C#, not C++

    Friday, October 16, 2009 3:43 PM

Answers

  • Reference types will not work with Marshal::SizeOf because of their default memory layout. You would typically use a value type for this sort of interop since value types have a sequential layout by default, which in this case means changing you "ref" to "value". If you have to use a reference type then you need to manually change its memory layout by using the StructLayoutAttribute attribute. In this case a LayoutKind of Sequential will work.

    Friday, October 16, 2009 4:06 PM

All replies

  • Reference types will not work with Marshal::SizeOf because of their default memory layout. You would typically use a value type for this sort of interop since value types have a sequential layout by default, which in this case means changing you "ref" to "value". If you have to use a reference type then you need to manually change its memory layout by using the StructLayoutAttribute attribute. In this case a LayoutKind of Sequential will work.

    Friday, October 16, 2009 4:06 PM
  • Thanks very much now it works

    But I can't use Marshal::PtrToStructure with value type....
    I can make struct with ^ pointers, witch I can easy convert to void * and back to struct ^ like this

    [StructLayout(LayoutKind::Sequential)]
    ref struct GRC
    {
         Bitmap ^ bt;
    
    };

    Friday, October 16, 2009 4:19 PM