2009-03-23 11 views
8

Todos los ejemplos que puedo encontrar usando DLLImport para llamar al código C++ desde C# pasan ints hacia adelante y hacia atrás. Puedo hacer que esos ejemplos funcionen bien. El método que necesito llamar toma dos estructuras como sus parámetros de importación, y no estoy exactamente claro cómo puedo hacer que esto funcione.¿Cómo uso DLLImport con structs como parámetros en C#?

Esto es lo que tengo que trabajar con:

I poseer el código C++, por lo que pueden hacer los cambios/adiciones a lo que necesitan.

Una aplicación de terceros va a cargar mi DLL al inicio y espera que el DLLExport se defina de cierta manera, por lo que realmente no puedo cambiar la firma del método que se está exportando.

La aplicación C# que estoy construyendo se va a utilizar como un contenedor para que pueda integrar esta pieza de C++ en algunas de nuestras otras aplicaciones, todas escritas en C#.

El C++ firma del método necesito llamar ve así

DllExport int Calculate (const MathInputStuctType *input, 
    MathOutputStructType *output, void **formulaStorage) 

Y MathInputStructType se define como la siguiente

typedef struct MathInputStuctTypeS { 
    int    _setData; 
    double    _data[(int) FieldSize]; 
    int    _setTdData; 
} MathInputStuctType; 

Respuesta

4

Desde la declaración informados, su código C# se verá algo como esto :

[DllImport("mydll.dll")] 
static extern int Calculate(ref MathInputStructType input, 
    ref MathOutputStructType output, ref IntPtr formulaStorage); 

Dependiendo de la estructura de MathInputStructTyp e y MathOutputStructType en C++, vas a tener que atribuir esas declaraciones de estructura también para que marquen correctamente.

+0

Falta el nombre de la función btw :) – leppie

+0

"va a tener que atribuir esas declaraciones de estructura también para que se consoliden correctamente". Bien, esta es la parte que realmente no entiendo. Agregué la estructura a mi pregunta. –

3

Para la estructura:

struct MathInputStuctType 
{ 
    int  _setData; 
    [MarshalAs(UnmanagedType.ByValArray, SizeConst = FieldSize)] 
    double[] _data; 
    int  _setTdData; 
} 
+0

No estoy seguro de si es 100% necesario pero debe establecer ArraySubType en UnmanagedType.R8 para el campo _data. – JaredPar

+0

Eso debería inferirse (supongo, ya que el marshaller es bastante bueno). – leppie

2

Es posible que desee ver en este proyecto en CodePlex, http://www.codeplex.com/clrinterop/Release/ProjectReleases.aspx?ReleaseId=14120. Debería ayudarlo a ordenar las estructuras correctamente.

+0

Esto se ve bien y todo, pero no importa qué DLL elijo, me sigue diciendo que espera un manifiesto. Parece una buena herramienta si funciona bien. –

+0

No sabía que era tan restrictivo, lo siento. – LanceSc

+0

Sin preocupaciones, gracias por la ayuda. –

Cuestiones relacionadas