2012-05-29 15 views

Respuesta

9

cadena Al pasar de C# para C++ debería ser sencillo. PInvoke administrará la conversión por usted.

Obteniendo una cadena de C++ a C# se puede hacer usando un StringBuilder. Necesita obtener la longitud de la cadena para crear un búfer del tamaño correcto.

Éstos son dos ejemplos de una API de Win32 conocido:

[DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)] 
static extern int GetWindowText(IntPtr hWnd, StringBuilder lpString, int nMaxCount); 
public static string GetText(IntPtr hWnd) 
{ 
    // Allocate correct string length first 
    int length  = GetWindowTextLength(hWnd); 
    StringBuilder sb = new StringBuilder(length + 1); 
    GetWindowText(hWnd, sb, sb.Capacity); 
    return sb.ToString(); 
} 


[DllImport("user32.dll", SetLastError = true, CharSet = CharSet.Auto)] 
public static extern bool SetWindowText(IntPtr hwnd, String lpString); 
SetWindowText(Process.GetCurrentProcess().MainWindowHandle, "Amazing!"); 
1

Muchas de las funciones que se encuentran en la API de Windows toman los parámetros de cadena o tipo de cadena. El problema con el uso del tipo de datos de cadena para estos parámetros es que el tipo de datos de cadena en .NET es inmutable una vez creado, por lo que el tipo de datos StringBuilder es la opción correcta aquí. Para un ejemplo examinar la función de la API GetTempPath()

definición API de Windows

DWORD WINAPI GetTempPath(
    __in DWORD nBufferLength, 
    __out LPTSTR lpBuffer 
); 

.NET prototipo

[DllImport("kernel32.dll")] 
public static extern uint GetTempPath 
(
uint nBufferLength, 
StringBuilder lpBuffer 
); 

Uso

const int maxPathLength = 255; 
StringBuilder tempPath = new StringBuilder(maxPathLength); 
GetTempPath(maxPathLength, tempPath); 
13

en el código C:

extern "C" __declspec(dllexport) 
int GetString(char* str) 
{ 
} 

extern "C" __declspec(dllexport) 
int SetString(const char* str) 
{ 
} 

al lado .net:

using System.Runtime.InteropServices; 


[DllImport("YourLib.dll")] 
static extern int SetString(string someStr); 

[DllImport("YourLib.dll")] 
static extern int GetString(StringBuilder rntStr); 

uso:

SetString("hello"); 
StringBuilder rntStr = new StringBuilder(); 
GetString(rntStr); 
+1

Su uso de 'const' es al revés. –

+0

@Ben Voigt: gracias, lo arreglaron. – sithereal

+0

Estos ejemplos explotaron con excepciones de pila en VisStudio 2012 hasta que agregué cdecl tanto al C# como al C .... extern "C" __declspec (dllexport) int __cdecl SetString (... y luego ... [DllImport (" YourLib.dlll ", CallingConvention = CallingConvention.Cdecl)] ... – user922020

Cuestiones relacionadas