编组.NET泛型类型

Gab*_*iel 9 .net c# generics interop marshalling

这是一个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>());
    }
}
Run Code Online (Sandbox Code Playgroud)

对M()的前四次调用成功,但在最后一次调用时,SizeOf会抛出ArgumentException:

"Type 'C`1[AClass]' cannot be marshaled as an unmanaged structure; no meaningful size or offset can be computed."
Run Code Online (Sandbox Code Playgroud)

为什么?具体来说,为什么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#类型(尽管继承可以提供公共头).

Jar*_*Par 9

任何互操作方案都不支持泛型作为规则.如果您尝试封送泛型类型或值,则P/Invoke和COM Interop都将失败.因此,我认为Marshal.SizeOf在这种情况下是未经测试或不受支持的,因为它是一个特定于元帅的函数.