我有一个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 ++。
答案 0 :(得分:0)
感谢@Zastai提供帮助。
事实证明,当在C ++中使用 char 作为结构时,它的C#对应物是字节。这解决了C#和C#之间结构尺寸的差异。 C ++。由于此错误,C#中的smMsg结构分配的内存超出了所需的内存。
使用新的smHeader定义更新问题。