Dưới đây là một chương trình C# mà cố gắng Marshal.SizeOf
trên một vài loại khác nhau:Marshalling NET kiểu generic
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>());
}
}
Bốn cuộc gọi đầu tiên đến M() thành công, nhưng trên người cuối cùng, sizeof ném một ArgumentException:
"Type 'C`1[AClass]' cannot be marshaled as an unmanaged structure; no meaningful size or offset can be computed."
Tại sao? Cụ thể, tại sao SizeOf choke trên C<AClass>
, nhưng không phải trên B
hoặc trên C<AStruct>
?
EDIT: Bởi vì nó đã được hỏi về trong các ý kiến, đây là "thực tế" Vấn đề truyền cảm hứng cho câu hỏi chủ yếu mang tính học thuật này: Tôi gọi vào một API C mà về cơ bản là một C chức năng hoạt động trên (con trỏ đến) nhiều loại cấu trúc C đơn giản khác nhau. Tất cả có chứa một tiêu đề chung theo sau là một trường, nhưng loại trường đó khác nhau trong các cấu trúc khác nhau. Cờ trong tiêu đề cho biết loại trường. (Lạ, vâng, nhưng đó là những gì tôi phải làm việc).
Nếu tôi có thể xác định một generic loại đơn C<T>
và một đơn C# extern khai M(C<T>)
, và sau đó gọi M(C<int>)
trên cùng một dòng, và M(C<double>)
ngày khác, tôi muốn có một giải pháp interop ngắn và ngọt ngào. Nhưng với câu trả lời của JaredPar, có vẻ như tôi phải tạo một kiểu C# riêng cho mỗi cấu trúc (mặc dù thừa kế có thể cung cấp tiêu đề chung).
Ngoại lệ nào được ném? –
ArgumentException, với thông điệp ông đã dán. –
@Philipp: chỉ cần chỉnh sửa để làm rõ điều đó, cảm ơn. – Gabriel