2012-06-18 33 views
15

Tôi đang sử dụng một lớp có trường StringHandle là giá trị IntPtr đại diện cho LPCWSTR bằng C++.đặt IntPtr ở C# .NET point thành chuỗi giá trị

internal IntPtr StringHandle; // LPCWSTR 

nói bây giờ mà tôi có một String: string x = "abcdefg"

Làm thế nào tôi có thể sử dụng chuỗi xử lý để trỏ đến đầu của chuỗi để nó giống như C++ LPCWSTR?

+0

Tại sao bạn muốn làm điều đó? –

+0

Tôi đang làm việc với giao diện chỉ tồn tại trong mã gốc (C++) vì vậy tôi đang sử dụng Interops từ .NET. tuy nhiên, lớp có StringHandle không phải của tôi và tôi không muốn thay đổi. –

+6

Vì đó là thư viện mà anh ấy đang làm việc với kỳ vọng. Không phải mọi thứ đều có một .NET wrapper được xây dựng cho nó, và ngay cả trong Framework, lớp Marshal cũng có thể sử dụng tốt khi bạn đang xử lý những thứ như các thông điệp Windows mức thấp. – KeithS

Trả lời

24

Bạn cần phải sao chép chuỗi vào bộ nhớ không được quản lý đầu tiên và sau đó nhận được IntPtr từ vị trí đó. Bạn có thể làm như vậy như:

IntPtr strPtr = Marshal.StringToHGlobalUni(x); 

cũng có, bạn cần phải chắc chắn để giải phóng bộ nhớ không được quản lý:

Marshal.FreeHGlobal(strPtr); 

đó là tốt nhất để làm tất cả điều này trong một thử/cuối cùng.

+0

Tôi thực sự cần một Marshal.StringToCoTaskMemUni này vì tôi đang sử dụng COM nhưng cảm ơn bạn –

1

Bạn muốn sử dụng một trong những phương pháp StringTo * trên lớp Marshal

7

Chuỗi được quản lý di chuyển trong bộ nhớ khi bộ thu gom rác tích hợp đống. Vì vậy, họ không có địa chỉ ổn định và không thể trực tiếp truyền tới LPCWSTR. Bạn sẽ cần phải ghim chuỗi bằng GCHandle.Alloc() để sử dụng GCHandle.AddrOfPinnedObject hoặc sao chép nó vào bộ nhớ không được quản lý bằng Marshal.StringToHGlobalUni().

Rất muốn sao chép nếu địa chỉ cần ổn định trong một thời gian.

+0

Có 'AddrOfPinnedObject' trên một chuỗi' cung cấp cho bạn một con trỏ tới dữ liệu ký tự ('LPCWSTR' như được đề cập trong câu hỏi) không? (Theo http://www.drdobbs.com/pinning-in-managed-c/184403869: Có) –

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