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#类型(尽管继承可以提供公共头).
任何互操作方案都不支持泛型作为规则.如果您尝试封送泛型类型或值,则P/Invoke和COM Interop都将失败.因此,我认为Marshal.SizeOf在这种情况下是未经测试或不受支持的,因为它是一个特定于元帅的函数.
| 归档时间: |
|
| 查看次数: |
6084 次 |
| 最近记录: |