从c#到c++的互操作传递结构

interop pass structure from c# to c++

本文关键字:结构 互操作 c++      更新时间:2023-10-16

c#代码:

[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
public struct Message
{
    public uint MsgId;
    public uint DLC;
    public uint Handle;
    public uint Interval;
    [MarshalAs(UnmanagedType.ByValArray, SizeConst = 64)]
    public byte[] Data;
};

我必须将这个结构发送到c++native.dll中的一个函数,如下所示:

    [DllImport("test.dll", CallingConvention = CallingConvention.Cdecl)]
    [return: MarshalAs(UnmanagedType.U4)]
    public static extern int AFT_iSetRTSECANWrapper(IntPtr Data);

我正在准备这样的缓冲区:

        Message frame = new Message();
        frame.MsgId = (uint)MsgId;
        frame.DLC = (uint)DLC;
        frame.Interval = (uint)Interval;
        frame.Data = new byte[64];
        for (int i = 0; i < Data.Length; i++)
        {
            frame.Data[i] = 11;
        }
        //Transmit message 
        int rawsize = Marshal.SizeOf(frame);
        IntPtr frameBuffer = Marshal.AllocHGlobal(rawsize);
        Marshal.StructureToPtr(frame, frameBuffer, false);
         AFT_iSetRTSECANWrapper(frameBuffer);

在c++中,i具有以下结构:

    typedef  struct { 
unsigned int MsgId;
unsigned int DLC;
unsigned int Handle;
unsigned int Interval;
    unsigned char Data[64]; 
 } Message;

要调用的函数是:

    extern "C" __declspec(dllexport) int AFT_iSetRTSECANWrapper(Message *data)

在这之后,我只是尝试访问消息中的字段与数据->DLC,但我一无所获。我搞不清楚这里出了什么问题。

我猜数据没有分配在与结构的其他部分相同的连续部分中,因此不会跨区域传输。尝试

[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
public struct Message
{
    public uint MsgId;
    public uint DLC;
    public uint Handle;
    public uint Interval;
    [MarshalAs(UnmanagedType.ByValArray, SizeConst = 64)]
    public byte[] Data = new byte[64];
};

对于C++位,而不是传输到intptr,直接传输

[DllImport("test.dll", CallingConvention = CallingConvention.Cdecl)]
[return: MarshalAs(UnmanagedType.U4)]
public static extern int AFT_iSetRTSECANWrapper([in,out] Message Data);

以发送您的消息

Message frame = new Message();
frame.MsgId = (uint)MsgId;
frame.DLC = (uint)DLC;
frame.Interval = (uint)Interval;
for (int i = 0; i < Data.Length; i++)
{
    frame.Data[i] = 11;
}
//Transmit message 
AFT_iSetRTSECANWrapper(frame);