none
Passing a struct from unmanaged C++ to C# RRS feed

  • Question

  • I think what I want to do is supposed to be fairly simple, but I can't seem to get it to work, and can't find info on how to do it.

    I have legacy C++ code that I need to have call into C# code.  I want to use a struct to pass data between the C++ and C# code.  I've decided to use a managed C++ wrapper over the C# code as the go-between.  The legacy C++ code will call into the managed C++, and it in turn will call the C# code.

    I have the interaction between the components working, and can call simple functions from the legacy C++ code to the C# code via the managed C++ code.  What I'm stuck on now is how to pass the struct from the C++ to the C# code.

    What I think I need to do is:

    1. Create typedef struct MY_STRUCT in the C++ code
    2. Make an equivalent public struct MY_STRUCT in the C# code (I used the PInvoke Signature Toolkit to do this). I think I have this correct
    3. In the managed C++ code, take the unmanaged version of the struct and convert it to the managed version
    4. Call the C# module with the managed version of the struct

    Is step #3 the right thing to do? If so, then that's where I'm stuck.  Do I need to use PtrToStructure in the C++ code?  Is there some easier way to have the marshaling done automatically, such as with a cast operator?

    Here's some pseudocode of what I want to do:

    Managed C++ code

    void WrapperModule::CallManagedCode( MY_STRUCT *pMyStruct )

    {

        gcroot< MyClass ^> _managedClass = gcnew MyClass();

        _managedClass->DoWork( *pMyStruct );  // What's the right way to pass this struct in?

    }

    C# code

    public struct MY_STRUCT

    {

       // Some fields

    }

    public void DoWork( MY_STRUCT myStruct )

    {

        // Do work

    }

    Also, if my managed C++ wrapper module needs to be able to access both structures, I assume I need to give the managed and unmanaged versions different names? If I don't, I get compiler errors about ambiguous names.

    Any help would be appreciated.  We have lots of C++ experience, and plenty of C# experience, but no experience in getting them to talk to each other.

    Thanks,

    David

    Wednesday, March 31, 2010 1:08 AM

All replies

  • It would be easier to answer the question if you could post the MY_STRUCT definition. For simple structs you might get by with a simple memcpy, for more complex ones you may need to do additional work.
    Mattias, C# MVP
    Wednesday, March 31, 2010 8:45 AM
    Moderator
  • I'd be happy to just get a simple struct to work for now.  Just wchar pointers and some integer values.  For now, I've got:

    typedef struct

    {

        WCHAR *pszString;

        int iValue;

    } MY_STRUCT;

    And in C#:

    /// [System.Runtime.InteropServices.StructLayoutAttribute(System.Runtime.InteropServices.LayoutKind.Sequential)]
    public struct MY_STRUCT

    {

           /// WCHAR*
            [System.Runtime.InteropServices.MarshalAsAttribute(System.Runtime.InteropServices.UnmanagedType.LPWStr)]
            public string pszString;

            /// int
            public int iValue;

    }

     

    Wednesday, March 31, 2010 2:44 PM