从 C++ DLL 返回的结构缺少数组数据中的第一个元素
Struct returned from C++ DLL missing first element in array data
我有一个 Unity5 程序,它使用通用结构 (smMsg) 将数据从 C++ DLL 发送到 C#。
该结构包含一个数组:
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 16)]
public float[] mtx;
这个数组将被视为 4x4 矩阵,因此大小为 16。
程序运行,接收数据进入C#对应结构体;但是,似乎从我的数组中我每次 运行 程序时都缺少 first 元素(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++ 中相等。
感谢@Zastai 的帮助。
事实证明,当在 C++ 中对结构使用 char 时,它在 C# 中的对应物是 byte。这解决了 C# 和 C++ 之间结构大小的差异。由于这个错误,C# 中的 smMsg 结构分配了比它需要的更多的内存。
问题已更新为新的 smHeader 定义。
我有一个 Unity5 程序,它使用通用结构 (smMsg) 将数据从 C++ DLL 发送到 C#。
该结构包含一个数组:
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 16)]
public float[] mtx;
这个数组将被视为 4x4 矩阵,因此大小为 16。
程序运行,接收数据进入C#对应结构体;但是,似乎从我的数组中我每次 运行 程序时都缺少 first 元素(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++ 中相等。
感谢@Zastai 的帮助。
事实证明,当在 C++ 中对结构使用 char 时,它在 C# 中的对应物是 byte。这解决了 C# 和 C++ 之间结构大小的差异。由于这个错误,C# 中的 smMsg 结构分配了比它需要的更多的内存。
问题已更新为新的 smHeader 定义。