Asi*_*sik 5 .net c# interop native marshalling
我想使用编组将本机结构读入 C# 类型。我对 Marshal 结构的方法是这样的:
T ReadObject<T>(BinaryReader br) {
var bytes = br.ReadBytes(Marshal.SizeOf(typeof(T)));
var handle = GCHandle.Alloc(bytes, GCHandleType.Pinned);
try {
return (T)Marshal.PtrToStructure(handle.AddrOfPinnedObject(), typeof(T));
}
finally {
handle.Free();
}
}
Run Code Online (Sandbox Code Playgroud)
现在这通常可以正常工作,问题出现在以下类型中:
[StructLayout(LayoutKind.Sequential, Pack=1)]
class SubData {
public short A1;
public short A2;
}
[StructLayout(LayoutKind.Sequential, Pack=1)]
class Data {
public short Id;
[MarshalAs(UnmanagedType.ByValArray, SizeConst=3)]
public SubData[] SubDatas;
}
Run Code Online (Sandbox Code Playgroud)
请注意,如果 SubData 是一个结构体,这可以正常工作!但是如果 SubData 是一个类,它会导致 Marshal.PtrToStructure 抛出 FatalExecutionEngineError。我想坚持使用类,因为有时我的类型有默认值,结构不能有字段初始值设定项或默认构造函数,而且其中一些类型相当大。
谢谢您的帮助。
编辑:错误消息是“运行时遇到了致命错误。错误的地址是 0x6af99aec,在线程 0x348 上。错误代码是 0xc0000005。此错误可能是 CLR 中的错误或不安全或非用户代码的可验证部分。此错误的常见来源包括 COM-interop 或 PInvoke 的用户封送错误,这可能会破坏堆栈。”
类是引用类型,因此当使用 Marshal.PtrToStructure 时,它将复制指针,并且在 Subdata 位置不复制任何值。
将 Subdata 声明为结构体时,将复制 subdata 的实际值。
因此,在进行编组时,必须使用结构体。您可能仍然有一个类,它将在构造函数中采用结构版本。
例如,您可以通过使用来证明这一点
大小
看看尺寸会有所不同。
| 归档时间: |
|
| 查看次数: |
3608 次 |
| 最近记录: |