Tengo una DLL administrado que exporta la función folowing:que vuelven punteros de no administrado a código administrado
SomeData* test();
Asumamos somedata como:
typedef struct _Data Data;
struct _Data{
int a;
int b;
}
Ahora quiero llamar a esta función desde C# código. Comienzo a definir el C# Struture necesaria para el cálculo personalizado así:
[StructLayout(LayoutKind.Sequential)]
public class SomeData
{
public Int32 a;
public Int32 b;
}
Y ahora, declaro la función administrada:
[DllImport("DynamicLibrary.dll", CharSet=CharSet.Auto)]
[return: MarshalAs(UnmanagedType.LPStruct)]
public static extern SomeData test();
Y en la función principal que tengo:
IntPtr ptr = test();
Al hacer esto, obtengo la excepción MarchalDirectiveException: "No se puede obtener el 'valor de retorno': Combinación de tipo administrado/no administrado no válido (Int/UInt debe emparejarse con SysInt o SysUInt)."
No asigné la memoria para SomeData en C# ya que espero que esta memoria esté asignada en la función C y ellos usaría Marshal.Copy para pasarla a la memoria administrada.
¿Alguna idea? Gracias
------------------------ EDITADO DESPUÉS JaredPar RESPUESTA ----------------- ---
De hecho, cometí un error al hacer frente al código de mi pregunta. La firma real administrado yo estaba usando era:
[DllImport ("DynamicLibrary.dll", charset = CharSet.Auto)] [
de retorno: MarshalAs (UnmanagedType.LPStruct)]
extern public static prueba IntPtr();
La respuesta de JaredPar sigue siendo relevante. Para obtener el comportamiento correcto, tengo 2 opciones:
1) Use la prueba de IntPtr externa pública estática(); ' (sin el atributo de MarshalAs) y luego acceder al puntero devuelto como sugirió JaredPar.
2) Utilice la prueba de SomeData (ex) de static extern public(); (con el atributo MarshalAs) y luego simplemente use SomeData sd = test();
Como puede ver en mi edición, cometí un error cuando escribí la pregunta. Su respuesta fue útil y funciona, pero prefiero usar la opción 2) de mi sección de edición. Gracias –