Aquí es un programa C# que intenta Marshal.SizeOf
en unos pocos tipos diferentes:Marshalling .NET tipos genéricos
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>());
}
}
Los primeros cuatro llamadas a M() tener éxito, pero en el último, SizeOf lanza una excepción ArgumentException:
"Type 'C`1[AClass]' cannot be marshaled as an unmanaged structure; no meaningful size or offset can be computed."
¿Por qué? Específicamente, ¿por qué SizeOf se estrangula en C<AClass>
, pero no en B
o en C<AStruct>
?
EDIT: Debido a que se le preguntó acerca de los comentarios, aquí está el problema del "mundo real" que inspiró a esta pregunta en su mayoría-académica: Voy a llamar a una API de C, que es básicamente un C función que opera en (punteros a) muchos tipos diferentes de estructuras C simples. Todos contienen un encabezado común seguido de un campo, pero el tipo de ese campo es diferente en diferentes estructuras. Una bandera en el encabezado indica el tipo de campo. (Extraño, sí, pero eso es con lo que tengo que trabajar).
Si pudiera definir un único tipo genérico C<T>
y una sola C# M(C<T>)
declaración externa, y luego llamar a M(C<int>)
en una línea, y M(C<double>)
en otro, tendría una solución de interoperabilidad corto y dulce. Pero dada la respuesta de JaredPar, parece que tengo que hacer un tipo de C# por separado para cada estructura (aunque la herencia puede proporcionar el encabezado común).
¿Qué excepción se produce? –
ArgumentException, con el mensaje que pegó. –
@Philipp: acaba de ser editado para aclarar eso, gracias. – Gabriel