2012-05-29 20 views

risposta

9

Passando stringa da C# per C++ dovrebbe essere semplice. PInvoke gestirà la conversione per te.

L'acquisizione di una stringa da C++ a C# può essere eseguita utilizzando StringBuilder. È necessario ottenere la lunghezza della stringa per creare un buffer della dimensione corretta.

Ecco due esempi di un noto API Win32:

[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

Un sacco di funzioni rilevate nell'API di Windows utilizzano parametri stringa o tipo stringa. Il problema con l'utilizzo del tipo di dati stringa per questi parametri è che il tipo di dati stringa in .NET è immutabile una volta creato in modo che il tipo di dati StringBuilder sia la scelta giusta qui. Per un esempio esaminare la funzione API GetTempPath()

definizione API di 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

nel codice C:

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

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

al fianco .net:

using System.Runtime.InteropServices; 


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

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

utilizzo:

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

vostro 'utilizzo const' è indietro. –

+0

@Ben Voigt: grazie, risolto. – sithereal

+0

Questi esempi sono esplosi con le eccezioni di stack in VisStudio 2012 fino a quando ho aggiunto cdecl sia al C# che al C .... extern "C" __declspec (dllexport) int __cdecl SetString (... e poi ... [DllImport (" YourLib.dlll ", CallingConvention = CallingConvention.Cdecl)] ... – user922020

Problemi correlati