2012-05-29 15 views

Odpowiedz

9

Przechodząc ciąg z C# C++ powinny być proste. PInvoke zarządza konwersją za Ciebie.

Pobieranie ciągu znaków z C++ do C# można wykonać za pomocą StringBuilder. Musisz uzyskać długość łańcucha, aby utworzyć bufor o odpowiednim rozmiarze.

Oto dwa przykłady znanego Win32 API:

[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

Wiele funkcji napotkanych w interfejsie API systemu Windows przyjmuje parametry łańcuchowe lub łańcuchowe. Problem z używaniem typu danych łańcuchowych dla tych parametrów polega na tym, że typ danych łańcucha w .NET jest niezmienny po utworzeniu, więc typ danych StringBuilder jest tu właściwym wyborem. Na przykład zbadać GetTempPath funkcji API()

definicja Windows API

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

prototyp NET

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

Wykorzystanie

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

w kodzie C:

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

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

w .net strony:

using System.Runtime.InteropServices; 


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

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

Wykorzystanie:

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

Twój 'wykorzystanie const' jest wstecznie. –

+0

@Ben Voigt: dzięki, naprawiłem to. – sithereal

+0

Te przykłady eksplodowały z wyjątkami stosu w VisStudio 2012, dopóki nie dodałem cdecl do C# i C ... extern "C" __declspec (dllexport) int __cdecl SetString (... a następnie ... [DllImport (" YourLib.dlll ", CallingConvention = CallingConvention.Cdecl)] ... – user922020