2008-10-02 26 views
18

Dada la siguiente función C en un archivo DLL:Marshal "char *" en C#

char * GetDir(char* path); 

¿Cómo P/Invocar esta función en C# y reunir la char * correctamente. .NET parece saber cómo hacer LPCTSTR pero cuando no puedo encontrar ninguna clasificación que no provoque que una NotSupportedException se dispare al llamar a esta función.

Respuesta

21

La respuesta de OregonGhost solo es correcta si el carácter * devuelto por GetDir se asigna en HGlobal o LocalAlloc. No recuerdo cuál pero el CLR asumirá que cualquier tipo de retorno de cadena de una función PInvoke fue asignado con uno u otro.

Una forma más robusta es escribir el retorno de GetDir para que sea IntPtr. Luego puede usar cualquiera de las funciones de Marshal.PtrToStringAnsi para obtener un tipo de cadena. También le brinda la flexibilidad de liberar la cuerda de la manera que elija.


[DllImport("your.dll", CharSet = CharSet.Ansi)] 
IntPtr GetDir(StringBuilder path); 

¿Puede darnos otras pistas sobre el comportamiento de GetDir? ¿Modifica la cadena de entrada? ¿Cómo se asigna el valor que se devuelve? Si puede proporcionar, puedo dar una respuesta mucho mejor.

+0

Ahhhh .... PtrToStringAnsi era que eso era lo que estaba buscando, mientras tanto había descubierto IntPtr, pero ahora me encuentro con un inconveniente ... Estoy usando .NETCF y PtrToStringAnsi solo está en el marco completo :( –

+0

Resulta que OpenNetCF tiene PtrToStringAnsi ... parece un problema resuelto. Esto marcará como aceptado tan pronto como pueda probar el código. –

+0

¿.NET sabe automáticamente ordenar a StringBuilder a un char * para los parámetros de entrada o era se necesita una biblioteca de terceros para que esto funcione? Gracias. – kmehta

12

Trate

[DllImport("your.dll", CharSet = CharSet.Ansi)] 
string GetDir(StringBuilder path); 

cadena se marshalled automáticamente a una cadena terminada en cero, y con la propiedad CharSet, le dice al Marshaller que debería utilizar ANSI en lugar de Unicode. Nota: Use cadena (o System.String) para un const char *, pero StringBuilder para un char *.

También puedes probar MarshalAs, como en this example.

+2

¿Conoces alguna razón por la cual 'cadena ansi = Marshal.PtrToStringAnsi (ptr);' tendría éxito, pero devolver una 'cadena' con' CharSet = CharSet.Ansi' fallaría? – jocull