none
Marshal a C# struct to native C++ RRS feed

  • Question

  • Platform is WS 2008 RC2, VS 2010.

    I have what I think should be a pretty straightforward marshalling situation, but it just isn't working as expected.

    Native Code:

    #pragma pack(push, 8)
    struct Handle
    {
    unsigned long Type;
    void* Value;
    void* Owner;
    };
    #pragma pack(pop)
    
    __declspec(dllexport) Handle __cdecl CreateStyleProvider(const wchar_t* provider);
    __declspec(dllexport) Handle __cdecl CreateOutputGroup(long ordinal, Handle style);
    

    The Handle struct is really just opaque data that gets passed around.

    C# code:

    [StructLayout(LayoutKind.Sequential, Pack=8)]
    public struct Handle
    {
      public uint Type;
      public IntPtr Value;
      public IntPtr Owner;
    }
    
    [DllImport("API.dll", CallingConvention=CallingConvention.Cdecl)]
        public static extern Handle CreateStyleProvider([MarshalAs(UnmanagedType.LPWStr)] string provider);
    
    [DllImport("API.dll", CallingConvention=CallingConvention.Cdecl)]
        public static extern Handle CreateOutputGroup(long ordinal, Handle style);
    
    

    Here is the C# code that calls

    Handle style = CreateStyleProvider("PlainText");
    Handle output = CreateOutputGroup(0, style);
    
    

    The call to CreateStyleProvider works and the style Handle that gets returned has the proper values in Type, Value, and Owner.  However, when style gets passed to the native CreateOutputGroup implementation, Type is always zero, Value has what should be in Type, and Owner has what should be in Value.

    Surely I am missing something really obvious.

    Thanks


    Kelly Hilliard
    Thursday, April 7, 2011 9:21 PM

Answers

  • This should be int, not long - a C++ "long" is a C# int:

     

    [DllImport("API.dll", CallingConvention=CallingConvention.Cdecl)]
      public static extern Handle CreateOutputGroup(int ordinal, Handle style);


    Reed Copsey, Jr. - http://reedcopsey.com
    If a post answers your question, please click "Mark As Answer" on that post and "Mark as Helpful".
    Friday, April 8, 2011 12:02 AM
    Moderator

All replies

  • This should be int, not long - a C++ "long" is a C# int:

     

    [DllImport("API.dll", CallingConvention=CallingConvention.Cdecl)]
      public static extern Handle CreateOutputGroup(int ordinal, Handle style);


    Reed Copsey, Jr. - http://reedcopsey.com
    If a post answers your question, please click "Mark As Answer" on that post and "Mark as Helpful".
    Friday, April 8, 2011 12:02 AM
    Moderator
  • Duh!  That's absolutely correct...should've seen that, but I was way too focused on the struct itself.  Thanks!
    Kelly Hilliard
    Friday, April 8, 2011 1:47 PM