none
problem with passing c-struct to c# RRS feed

  • Question

  • Hello,

    after searching several topics in this forum, I couldn't found a solution for following problem:

    I have structs in C:

    typedef struct ObjectHeaderBase_t
    {
        DWORD     mSignature;
        WORD       mHeaderSize;
        WORD       mHeaderVersion;
        DWORD     mObjectSize; 
        DWORD     mObjectType; 
    } ObjectHeaderBase;
    
    typedef struct ObjectHeader_t
    {
        ObjectHeaderBase  mBase; 
        DWORD               mObjectFlags;
        DWORD               mReserved;
        ULONGLONG         mObjectTime; 
    } ObjectHeader;
    
    typedef struct Message_t
    {
        ObjectHeader mHeader;
        WORD            mChannel; 
        BYTE            mFlags;
        BYTE            mDLC; 
        DWORD           mID;
        BYTE            mData[8];
    } Message;


    in C# I declared the structs as below:

    [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
        public struct ObjectHeaderBase
        {
          public uint      mSignature; 
          public ushort    mHeaderSize;
            public ushort    mHeaderVersion;
            public uint      mObjectSize; 
            public uint      mObjectType;         
        }
    
        [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
        public struct ObjectHeader
        {
          public ObjectHeaderBase mBase;
          public uint                mObjectFlags; 
          public uint                mReserved;
          public ulong               mObjectTimeStamp;
        }
    
        [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
        public struct Message
        {
          public ObjectHeader mHeader;
          public ushort          mChannel;
          public byte            mFlags; 
          public byte            mDLC;
          public uint            mID;
          [MarshalAs( UnmanagedType.LPArray, SizeConst=8) ]
          public byte[]          mData;
        }
    with the following functions, I try to get the struct:

    /// declaration in C
    MYDLLAPI( BOOL) ReadObject( HANDLE hFile, ObjectHeaderBase* pBase);

    ///C#
    [

    DllImport( "myDll.dll", CharSet=CharSet.Unicode )]
    extern static bool ReadObject(IntPtr hFile, [MarshalAs(UnmanagedType.Struct)] ref ObjectHeaderBase pBase);

    ...
    Message msg;

    msg.mHeader.mBase = HeaderBaseParam;
    msg.mData = new byte[8];
    bSuccess = ReadObject(mFileHandle, ref msg.mHeader.mBase);
    ...


    when calling the function in C# the struct won't be passed. Normally the data in msg and msg.mHeader should be set by passing the mBase-data.
    Because I thought the Dll is not working, I programmed code in c, which does the same as the c#-programme and it works fine.

    Does anybody know where the misstake is? I tried to play with several Marshalling options but no success.

    Thanks
    jojo

    Thursday, November 5, 2009 2:01 PM

Answers

  • Thanks to Captain Kernel ;-))

    The fixed-command "fixed" it.
    The problem was the byte-field of the message-struct.
    When using:

    public unsafe struct Message
    {
          public ObjectHeader mHeader;
          public ushort          mChannel;
          public byte            mFlags;
          public byte            mDLC;
          public uint            mID;
          public fixed byte   mData[8];
    }

    it works fine.
    Maybe there is another solution which is more elegant in C# without using unsafe. When somebody knows a way, please response.

    thanks jojo
    • Marked as answer by jojo82 Friday, November 6, 2009 8:20 AM
    Friday, November 6, 2009 8:19 AM