将结构数组从 C# 封送到 VC++
Marshalling array of struct from C# to VC++
我正在尝试将结构数组从 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)
)。
相关文章:
- 如何循环打印顶点结构
- 通过方法访问结构
- 使用不带参数的函数访问结构元素
- 预处理器:插入结构名称中的前一个行号
- 为什么在没有显式默认构造函数的情况下,将另一个结构封装在联合中作为成员的结构不能编译
- 孤立代码块在结构中引发异常
- 有什么方法可以遍历结构吗
- 如何在 C# 中映射双 C 结构指针?
- 嵌套的C 常数数据结构,没有初始化列表或明确命名所有节点-VC 2012过早破坏了内部元素
- 如何将结构打包从 VC++ 转换为 GCC
- VC++的一个大错误?为什么初始值设定项列表不对结构进行值初始化
- 扩展typedef结构(与VC++11兼容)
- vc++2010/2012:std::包含unique_ptr编译器错误的结构的向量
- VC++ 中的文件时间结构
- 将结构数组从 C# 封送到 VC++
- 了解 VC++ 项目/解决方案资源管理器文件层次结构
- 使用c++/vC++将结构数组和2d数组传递给函数
- VC++2013 中嵌套可变参数模板化结构的别名
- vc++ 2005之后在结构体中使用未指定的std::_ARRAY
- 在VC++中,将常量字符赋给结构内部的字符数组