C#: marshalling a struct that contains arrays

前端 未结 3 1903
伪装坚强ぢ
伪装坚强ぢ 2021-01-02 21:25

I am doing some C# interop work. I have the following struct:

#pragma pack(push,1)
typedef struct
{
    unsigned __int64 Handle;
    LinkType_t Type;
    Lin         


        
3条回答
  •  醉话见心
    2021-01-02 21:30

    What Anton Tykhyy says is correct. I just want to clarify with some examples. Using 'fixed' works, but that forces you to use 'unsafe' as well. I like to avoid using unsafe wherever possible. Using Marshal is a way to get around that.

    First, let's say that I have a library that was created in C with the following definitions.

    typedef struct {
        int messageType;
        BYTE payload[60];
    } my_message;
    
    /**
    * \param[out] msg    Where the message will be written to
    */
    void receiveMessage(my_message *msg);
    
    /*
    * \param[in] msg    The message that will be sent
    */
    void sendMessage(my_message *msg);
    

    In C#, the following structure would be equivalent to the one in C.

    [StructLayout(LayoutKind.Sequential, Size = 64), Serializable]
    struct my_message
    {
        int messageType;
        [MarshalAs(UnmanagedType.ByValArray,SizeConst = 60)]
        byte[] payload;
    
        public initializeArray()
        {
            //explicitly initialize the array
            payload = new byte[60];
        }
    }
    

    Since the msg in receiveMessage() is documented as [out], you don't need to do anything special to the array in the structure before passing it to the function. i.e.:

    my_message msg = new my_message();
    receiveMessage(ref msg);
    byte payload10 = msg.payload[10];
    

    Since the msg in sendMessage() is documented as [in], you will need to fill the array before calling the function. Before filling the array, the array needs to be explicitly instantiated before using it. i.e.:

    my_message msg = new my_message();
    msg.initializeArray();
    msg.payload[10] = 255;
    sendMessage(ref msg);
    

    Calling initializeArray() should instantiate the array in the previously allocated space created within the struct for this array.

提交回复
热议问题