Hier ist ein C# Programm, das Marshal.SizeOf
auf ein paar verschiedenen Arten versucht:Rangierung .NET generische Typen
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>());
}
}
Die ersten vier Anrufe M() erfolgreich zu sein, aber auf dem letzten, wirft SizeOf ein Argument:
"Type 'C`1[AClass]' cannot be marshaled as an unmanaged structure; no meaningful size or offset can be computed."
Warum? Insbesondere, warum SizeOf auf C<AClass>
, aber nicht auf B
oder auf C<AStruct>
Drossel?
EDIT: Weil es in den Kommentaren gefragt wurde, hier ist das „real-world“ Problem, dass diese meist akademische Frage inspiriert: ich in einen C-API bin aufrufe, die im Grunde eine C Funktion, die auf viele verschiedene Arten einfacher C-Strukturen (Zeiger auf) einwirkt. Alle enthalten einen gemeinsamen Header gefolgt von einem Feld, aber der Typ dieses Feldes unterscheidet sich in verschiedenen Strukturen. Ein Flag in der Kopfzeile zeigt den Typ des Feldes an. (Seltsam, ja, aber damit muss ich arbeiten).
Wenn ich einen einzelnen generischen Typen C<T>
und eine einzelnen C# extern-Deklaration M(C<T>)
definieren könnte und dann M(C<int>)
auf einer Linie nennen, und M(C<double>)
auf einem anderen, würde ich eine kurze und süße Interop Lösung. Aber angesichts JaredPars Antwort scheint es, dass ich für jede Struktur einen eigenen C# -Typ machen muss (obwohl die Vererbung den gemeinsamen Header liefern kann).
Welche Ausnahme wird ausgelöst? –
ArgumentException mit der Nachricht, die er eingefügt hat. –
@Philipp: gerade bearbeitet, um das zu klären, danke. – Gabriel