2010-08-21 28 views
6

Vì vậy, tôi làm việc trong clr, tạo dll .net trong hình ảnh C++.Làm thế nào để biến hệ thống :: String^thành std :: string?

Tôi trù mã như:

static bool InitFile(System::String^ fileName, System::String^ container) 
{ 
    return enc.InitFile(std::string(fileName), std::string(container)); 
} 

có encoder mà normaly resives std :: string. nhưng ở đây trình biên dịch (visual studio) mang lại cho tôi lỗi C2664 nếu tôi loại bỏ các đối số từ std :: string và C2440 mà nói chung là như nhau. VS nói với tôi rằng nó chỉ có thể không chuyển đổi hệ thống :: String^thành std :: string.

Vì vậy, tôi buồn ... tôi phải làm gì để biến System :: String^thành std :: string?

Cập nhật:

Bây giờ với sự giúp đỡ của bạn tôi có mã như vậy

#include <msclr\marshal.h> 
#include <stdlib.h> 
#include <string.h> 
using namespace msclr::interop; 
namespace NSSTW 
{ 
    public ref class CFEW 
    { 
public: 
    CFEW() {} 

    static System::String^ echo(System::String^ stringToReturn) 
    { 
     return stringToReturn; 
    } 

    static bool InitFile(System::String^ fileName, System::String^ container) 
    { 
     std::string sys_fileName = marshal_as<std::string>(fileName);; 
     std::string sys_container = marshal_as<std::string>(container);; 
     return enc.InitFile(sys_fileName, sys_container); 
    } 
... 

nhưng khi tôi cố gắng để biên dịch nó mang lại cho tôi C4996

lỗi C4996: 'msclr :: interop :: error_reporting_helper < _To_Type, _From_Type> :: marshal_as ': Chuyển đổi này không được thư viện hoặc tệp tiêu đề cần thiết cho chuyển đổi này không được bao gồm. Vui lòng tham khảo tài liệu về 'Cách: Mở rộng Thư viện Marshaling' để thêm phương thức marshaling của riêng bạn.

phải làm gì?

+4

Bạn đã bao gồm 'msclr \ marshal.h'. Hãy thử 'msclr \ marshal_cppstd.h'. –

+0

@ Chris Schmich: cảm ơn bạn - bây giờ nó biên dịch hoàn hảo =) – Rella

Trả lời

6

Nếu bạn đang sử dụng VS2008 hoặc mới hơn, bạn có thể thực hiện việc này rất đơn giản với automatic marshaling added to C++. Ví dụ, bạn có thể chuyển đổi System::String^-std::string qua marshal_as:

System::String^ clrString = "CLR string"; 
std::string stdString = marshal_as<std::string>(clrString); 

Đây là marshaling cùng sử dụng cho P/Invoke gọi.

+0

Tôi thích ý tưởng nhưng làm thế nào để khai báo marshal_as trong mã của tôi? nơi và những gì tôi sẽ viết để tuyên bố nó (để thoát khỏi lỗi C2065), tôi sử dụng VS2008 – Rella

+1

Để đi từ 'System :: String ^' đến 'std :: string', bạn cần phải' #include 'where' marshal_as' được khai báo. –

+0

khi tôi thử #include nó cho tôi lỗi nghiêm trọng C1083 ... vì vậy tôi đã chỉnh sửa mã và đăng nó ở đây trong Câu hỏi (tôi sử dụng những gì họ đã sử dụng trong MS MSDN ví dụ) ... bạn có thể xem xin vui lòng. – Rella

4

Từ bài viết How to convert System::String^ to std::string or std::wstring trên MSDN:

void MarshalString (String^s, string& os) 
{ 
    using namespace Runtime::InteropServices; 
    const char* chars = 
     (const char*)(Marshal::StringToHGlobalAnsi(s)).ToPointer(); 
    os = chars; 
    Marshal::FreeHGlobal(IntPtr((void*)chars)); 
} 

Cách sử dụng:

std::string a; 
System::String^ yourString = gcnew System::String("Foo"); 
MarshalString(yourString, a); 
std::cout << a << std::endl; // Prints "Foo" 
3

Bạn cần phải bao gồm marshal_cppstd.h để chuyển đổi chuỗi^để std :: string.

Bạn không đề cập đến việc bạn quan tâm đến tất cả các ký tự không phải ascii hay không. Nếu bạn cần unicode (và nếu không, tại sao không !?), có một marshal_as trả về một std :: wstring.

Nếu bạn đang sử dụng utf8, bạn sẽ phải tự cuộn. Bạn có thể sử dụng vòng lặp đơn giản:

System::String^ s = ...; 
std::string utf8; 
for each(System::Char c in s) 
    // append encoding of c to "utf8"; 
Các vấn đề liên quan