为什么我不能为这个 C# 结构做 Marshal.SizeOf()
本文关键字:Marshal SizeOf 结构 不能 为什么 | 更新日期: 2023-09-27 18:35:34
我尝试调用代码int size = Marshal.SizeOf(typeof(MyStruct))
但它抛出以下异常:
类型"MyStruct"不能封送为非托管结构;不能计算有意义的大小或偏移量。
我的结构如下:
[StructLayout(LayoutKind.Sequential)]
public struct MyStruct
{
[MarshalAs(UnmanagedType.U4)]
public UInt32 version;
[MarshalAs(UnmanagedType.FunctionPtr)]
public IntPtr Start;
[MarshalAs(UnmanagedType.FunctionPtr)]
public IntPtr Stop;
// And a bunch more IntPtr, all declared the same way.
}
该结构应该传递给 C-land,其中 C 代码将使用它的内容作为函数指针。我看不出计算大小会如何失败,有人可以帮忙吗?
UnmanagedType.FunctionPtr 要求字段为委托类型。 在结构封送后,它将是 C 端的函数指针。 使用[元帅]是多余的,代表已经这样被封送了。 所以,粗略地说:
[StructLayout(LayoutKind.Sequential)]
public struct MyStruct
{
[MarshalAs(UnmanagedType.U4)]
public UInt32 version;
public Action Start;
public Func<bool> Stop;
// etc..
}
更改委托类型以匹配相应 C 函数指针的函数签名。 通常必须声明自己的委托类型,以便为其指定 [UnmanagedFunctionPointer] 属性以匹配 C 函数的调用约定。 通常调用Convention.Cdecl,而不是Stdcall的默认。
初始化这样的结构时必须非常小心。 您创建并分配给字段的委托对象必须在其他位置引用,以防止它们被垃圾回收。 通过将它们存储在保证只要 C 代码可以进行调用就存在的时间的类对象中,将它们存储在静态变量中或使用 GCHandle.Alloc() 显式添加引用
有很多方法可以射击你的脚,祝你好运:)