这里有一个C#程序,它尝试对几种不同类型使用Marshal.SizeOf
:
using System;
using System.Runtime.InteropServices;
[StructLayout(LayoutKind.Sequential)]
class AClass { }
[StructLayout(LayoutKind.Sequential)]
struct AStruct { }
[StructLayout(LayoutKind.Sequential)]
class B { AClass value; }
[StructLayout(LayoutKind.Sequential)]
class C<T> { T value; }
class Program
{
static void M(object o) { Console.WriteLine(Marshal.SizeOf(o)); }
static void Main()
{
M(new AClass());
M(new AStruct());
M(new B());
M(new C<AStruct>());
M(new C<AClass>());
}
}
前四次调用M()成功,但在最后一次调用时,SizeOf抛出了ArgumentException异常:
"Type 'C`1[AClass]' cannot be marshaled as an unmanaged structure; no meaningful size or offset can be computed."
为什么?具体而言,为什么SizeOf在
C<AClass>
上会出错,而在B
或C<AStruct>
上不会出错?
编辑:因为评论中提到了这个问题的“现实世界”问题:我正在调用一个C API,它基本上是一个操作(指针)许多不同类型简单C结构的C函数。所有结构都包含一个共同的头部,后跟一个字段,但该字段的类型在不同的结构中是不同的。头部中的标志表示字段的类型。(很奇怪,但这就是我必须处理的内容)。如果我可以定义一个通用类型
C<T>
和一个C# extern声明M(C<T>)
,然后在一行上调用M(C<int>)
,在另一行上调用M(C<double>)
,那么我将拥有一个简短而甜美的互操作解决方案。但鉴于JaredPar的答案,似乎我必须为每个结构制作单独的C#类型(尽管继承可以提供共同的头部)。