2012-05-29 29 views
15

Tôi đã cố gắng để gửi một chuỗi đến/từ C# đến/từ C++ trong một thời gian dài nhưng không quản lý để có được nó làm việc chưa ...Làm thế nào để vượt qua các chuỗi từ C# đến C++ (và từ C++ đến C#) bằng cách sử dụng DLLImport?

Vì vậy, câu hỏi của tôi rất đơn giản:
Có ai biết một số cách để gửi một chuỗi từ C# đến C + + và từ C + + để C#?
(Một số mã mẫu có thể hữu ích)

Trả lời

9

Đi qua chuỗi từ C# C++ nên thẳng về phía trước. PInvoke sẽ quản lý việc chuyển đổi cho bạn.

Nhận chuỗi từ C++ đến C# có thể được thực hiện bằng cách sử dụng một StringBuilder. Bạn cần lấy độ dài của chuỗi để tạo bộ đệm có kích thước chính xác.

Dưới đây là hai ví dụ về một Win32 API nổi tiếng:

[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

Rất nhiều chức năng gặp phải trong API Windows lấy các tham số kiểu chuỗi hoặc chuỗi. Vấn đề với việc sử dụng kiểu dữ liệu chuỗi cho các tham số này là kiểu dữ liệu chuỗi trong .NET là bất biến khi được tạo nên kiểu dữ liệu StringBuilder là lựa chọn đúng ở đây. Đối với một ví dụ kiểm tra chức năng API GetTempPath()

nét Windows API

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

NET nguyên mẫu

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

Cách sử dụng

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

trong mã c của bạn:

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

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

ở bên cạnh .net:

using System.Runtime.InteropServices; 


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

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

sử dụng:

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

'sử dụng const' của bạn là ngược. –

+0

@Ben Voigt: cảm ơn, đã sửa nó. – sithereal

+0

Những ví dụ này phát nổ với ngăn xếp ngoại lệ trong VisStudio 2012 cho đến khi tôi thêm cdecl vào cả C# và C .... extern "C" __declspec (dllexport) int __cdecl SetString (... và sau đó ... [DllImport (" YourLib.dlll ", CallingConvention = CallingConvention.Cdecl)] ... – user922020

Các vấn đề liên quan