2008-09-11 31 views
40

Cách được chấp thuận để chuyển đổi từ char * thành System :: string và ngược lại trong C++/CLI là gì? Tôi tìm thấy một vài tài liệu tham khảo để marshal_to <> chức năng templated trên Google, nhưng nó xuất hiện rằng tính năng này không bao giờ thực hiện cắt cho Visual Studio 2005 (và không phải là trong Visual Studio 2008 hoặc, AFAIK). Tôi cũng đã thấy một số mã trên Stan Lippman's blog, nhưng nó là từ năm 2004. Tôi cũng đã thấy Marshal :: StringToHGlobalAnsi(). Có phương pháp nào được coi là "thực hành tốt nhất" không?Cách tốt nhất để chuyển đổi giữa char * và System :: String trong C++/CLI

Trả lời

18

Có một cái nhìn tổng quan tốt ở đây (hỗ trợ marshaling này bổ sung cho VS2008): http://www.codeproject.com/KB/mcpp/OrcasMarshalAs.aspx

+7

Cảm ơn, nhưng đó là một lời giải thích dài dòng. Điều này đi sâu vào vấn đề: '#include // marshal_context context; // my_c_string = context.marshal_as (my_csharp_string); ' – gatopeich

+0

Đối với những người tự hỏi, không gian tên đầy đủ cho ngữ cảnh là 'msclr :: interop :: marshal_context' – Mugen

1

Những gì chúng tôi đã làm được tạo thành một đối tượng C++ \ CLI giữ chuỗi trong mã không bị sửa đổi và sẽ đưa ra các bản sao đã được mang của mục đó. Mã chuyển đổi trông rất giống với những gì Stan có trên blog của anh ấy (tôi không thể nhớ chính xác) (Nếu bạn sử dụng mã của anh ta chắc chắn rằng bạn cập nhật nó để sử dụng delete []) nhưng chúng tôi đảm bảo rằng trình hủy sẽ xử lý tất cả các yếu tố chưa được khắc phục của đối tượng. Đây là một chút thổi phồng nhưng chúng tôi không có rò rỉ khi chúng ta gắn vào các mô-đun mã C++ kế thừa.

70

Hệ thống :: String có một constructor mà phải mất một char *:

using namespace system; 
const char* charstr = "Hello, world!"; 
String^ clistr = gcnew String(charstr); 
Console::WriteLine(clistr); 

Bắt một char * lại là khó hơn một chút, nhưng không quá tệ:

IntPtr p = Marshal::StringToHGlobalAnsi(clistr); 
char *pNewCharStr = static_cast<char*>(p.ToPointer()); 
cout << pNewCharStr << endl; 
Marshal::FreeHGlobal(p); 
+4

+1, System :: String constructor cũng có độ dài và mã hóa! –

+5

'Marshal :: StringToHGlobalAnsi' là một tùy chọn nghèo so với' marshal_context' (như được đề cập bởi Matthew), sử dụng RAII để tự động giải phóng bộ đệm. Chưa kể rằng cái tên hoàn toàn sai, nó không trả về một 'HGLOBAL' chút nào. –

1

Tôi đã tạo một vài phương pháp trợ giúp. Tôi cần làm điều này để chuyển từ thư viện Qt cũ sang chuỗi CLI. Nếu bất cứ ai có thể thêm vào điều này và cho tôi biết nếu nó có vẻ như tôi có một rò rỉ bộ nhớ và những gì tôi có thể làm để sửa chữa nó, tôi sẽ được đánh giá cao nhất.

void MarshalString ( String^s, wstring& os) { 
    using namespace Runtime::InteropServices; 
    const wchar_t* char = (const wchar_t*)(Marshal::StringToHGlobalUni(s)).ToPointer(); 
    os = char; 
} 
QString SystemStringToQt(System::String^ str) 
{ 
    wstring t; 
    MarshalString(str, t); 
    QString r = QString::fromUcs2((const ushort*)t.c_str()); 
    return r; 
} 
+0

Có thể phải đối chiếu Marshal :: FreeHGlobal (IntPtr ((void *) chars)); nó –

+0

@Pat có xin lỗi tôi nên có cập nhật này sau này. Tôi đã làm cho nó hoạt động tốt ngay bây giờ. Di chuyển nó sang .NET tăng hiệu suất của ứng dụng này lên gấp 3 lần. Ngay cả những thứ xung quanh. – dko

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