从C ++ DLL返回的Struct缺少数组数据

时间:2016-02-26 21:17:44

标签: c# c++ arrays dll unmanaged

我有一个Unity5程序,它使用一个通用结构( smMsg )将数据从C ++ DLL发送到C#。

结构包含一个数组:

[MarshalAs(UnmanagedType.ByValArray, SizeConst = 16)]
public float[] mtx; 

此数组被视为4x4矩阵,因此常量大小为16。

程序工作,将数据接收到C#对应的结构中;但是,似乎从我的数组中我每次运行程序时都缺少第一个元素(mtx [0])。看起来每个其他元素都向左移动了最后一个元素的额外0,保持了它们所处的顺序。

我认为这是因为我使用的UnmanagedType,但是其他来源告诉我UnmanagedType.ByValArray是正确的类型。

任何人都有指导或领导我可以遵循以帮助解决这个问题吗?

复制数据的过程

C#:

// DLL Import
[DllImport(DLL_NAME, EntryPoint = "smCopy")] 
private static extern void smCopyData(IntPtr dest, IntPtr len); //const VOID *dest, SIZE_T len);

// Copying data logic
{
    //  allocate intptr to buffer
    var len = Marshal.SizeOf(typeof(smMsg));
    IntPtr msg_intptr = Marshal.AllocHGlobal(len); 

    try
    {
        //  Copy data
        smCopyData(msg_intptr, (IntPtr)(len));

        //  Set POINTER data to struct
        return_msg = (smMsg)Marshal.PtrToStructure(msg_intptr, typeof(smMsg));

    }
    finally
    {
        //  free unmanaged memory!
        Marshal.FreeHGlobal(msg_intptr);
    }
}

C ++

// Function called via DLL
void DLL_API smCopy(const VOID *dest, SIZE_T len)
{
    CopyMemory((PVOID)(dest), (PVOID)(mapBuffer), len);
}

结构定义

我感兴趣的主要数据是float[] mtx

[StructLayout(LayoutKind.Sequential)]
public struct smMsg 
{
   public smHeader header;
   public smData data; 
}

[StructLayout(LayoutKind.Sequential)]
public struct smData
{
   // Event ID.
   public int evtId;
   public int status;

   // Floating point values. Actual data to be transmitted.
   [MarshalAs(UnmanagedType.ByValArray, SizeConst = 16)]
   public float[] mtx; 
}

[StructLayout(LayoutKind.Sequential)]
public struct smHeader
{
   public ushort chkSum;
   public char numWords;
   public char msgType;
}

更新2/29

感谢@Zastai,我最终能够恢复丢失的元素。事实证明,我想使用“byte”作为数据类型而不是char,因为char是C#unicode类型(短)。

我最终做的是将我的smHeader更改为:

[StructLayout(LayoutKind.Sequential)]
public struct smHeader   
{
   public ushort chkSum; 

   public byte numWords;

   public byte msgType;
}

..反过来将smHeader大小从6降低到4,将smMsg结构大小设置为相同的C#和& C ++。

1 个答案:

答案 0 :(得分:0)

感谢@Zastai提供帮助。

事实证明,当在C ++中使用 char 作为结构时,它的C#对应物是字节。这解决了C#和C#之间结构尺寸的差异。 C ++。由于此错误,C#中的smMsg结构分配的内存超出了所需的内存。

使用新的smHeader定义更新问题。