将结构数组从 C# 封送到 VC++
本文关键字:VC++ 结构 数组 | 更新日期: 2023-09-27 18:33:52
我正在尝试将结构数组从 C# 封送到 VC++。
C++函数如下所示:
void myFunc(tFileListEntry* fileList);
tFileListEntry
定义为:
typedef struct FILE_LIST
{
uint16_t FileGroupCounter;
uint32_t FileID;
uint16_t NumbSamples;
} tFileListEntry;
在 C# 中,我像这样声明了函数:
[DllImport("MyLib", EntryPoint = "myFunc", CallingConvention = CallingConvention.Cdecl)]
public static extern void myFunc( [In, MarshalAs(UnmanagedType.LPArray)] tFileListEntry[] fileList);
tFileListEntry
定义为:
[StructLayout(LayoutKind.Sequential)]
public class tFileListEntry
{
public tFileListEntry(UInt16 fileGroupCounter, UInt32 fileId, UInt16 numbSamples)
{
FileGroupCounter = fileGroupCounter;
FileID = fileId;
NumbSamples = numbSamples;
}
public UInt16 FileGroupCounter;
public UInt32 FileID;
public UInt16 NumbSamples;
}
我可以在 C# 代码以及C++库中设置断点。在托管端,值看起来是正确的,但在非托管端,我只得到垃圾。
我用Marshal.SizeOf()
(在 C# 中)和sizeof()
(在 C++ 中)验证了结构的大小两侧都是 12 个字节,所以我认为填充/打包在这里不是问题。
我做错了什么?
我认为
这里的问题是在 C# 方面,您将其声明为类,而不是结构。
这意味着,当您在 C# 端创建数组时,数组的每个元素都是一个引用(4 或 8 个字节,具体取决于架构),而不是结构(12 个字节),以及你所看到的结果。
尝试将 C# 类更改为结构。
看起来问题是我在 C# 端将tFileListEntry
定义为class
。当我将其更改为struct
时,一切正常。
有趣的是,我在同一库中还有另一个接受单个struct
(不是数组)的C++函数,我可以成功地封送 C# class
(使用 MarshalAs(UnmanagedType.LPStruct)
)。