Visual Studio 2010 공식 팀 블로그 @vsts2010

Posted by 흥배

3) String^ C/C++ 문자열로 변환

 

1)번에서는 C/C++의 문자열을 String^로 변환하는 방법에 대해서 설명했습니다.

이번에는 String^ char* wchr_t*로 변환하는 방법에 대해서 설명합니다.

 

아래의 예제 코드를 봐 주세요

 

#include <string>

#include <msclr\marshal_cppstd.h>

 

using namespace System;

using namespace msclr::interop;

 

int main()

{

           System::String^ s0 = L"비주얼스튜디오2010 팀블로그";

          

           // 방법 1

           std::string tmp = marshal_as<std::string>(s0);

           const char* s1 = tmp.c_str();

           std::cout << "String^ -> string : " << s1 << std::endl;

 

           // 방법 2

           const char* s2;

           const wchar_t* s3;

           {

                     marshal_context ctx;

                     s2 = ctx.marshal_as<const char*>(s0);

                     s3 = ctx.marshal_as<const wchar_t*>(s0);

            

                     std::cout << "String^ -> char* : " << s2 << std::endl;

                    

                     setlocale(LC_ALL, "");

                     std::wcout << "String^ -> wchar_t : " << s3 << std::endl;

           }

 

           getchar();

           return 0;

}

 

String^ char* wchr_t*로 변환하는 방법은 두 가지가 있습니다.

 


첫 번째 std::string 사용


가장 간단한 방법입니다만 불필요한 std::string을 사용해야 단점이 있습니다.

std::string tmp = marshal_as<std::string>(s0);

const char* s1 = tmp.c_str();

std::cout << "String^ -> string : " << s1 << std::endl;

 

 

두 번째 marshal_context 사용


첫 번째 방법에서 std::string을 사용한 이유는 다름이 아니고 메모리 확보 때문입니다.

마샬링을 통해서 char* wchar_t*에 메모리 주소를 저장합니다. 문자열 그 자체를 복사하는 것이 아닙니다. 그래서 변환한 문자열을 저장할 메모리 주소를 확보하고 사용 후에는 해제를 해야 합니다. 메모리 확보와 해제를 위해서 marshal_context를 사용합니다.

marshal_context는 변환에 필요한 메모리를 확보하고, 스코프를 벗어날 때 메모리를 해제합니다.

const char* s2;

const wchar_t* s3;

{

           marshal_context ctx;

           s2 = ctx.marshal_as<const char*>(s0);

           s3 = ctx.marshal_as<const wchar_t*>(s0);

}

 

String^ C/C++ 문자열로 변환할 때는 std::string + marshal_as marshal_context 둘 중 하나를 선택하여 사용합니다.

 




참고

http://msdn.microsoft.com/en-us/library/bb384865.aspx

http://msdn.microsoft.com/ko-kr/library/bb531313%28VS.90%29.aspx

http://codezine.jp/article/detail/4774

저작자 표시
크리에이티브 커먼즈 라이선스
Creative Commons License

댓글을 달아 주세요

  1. 좋은 내용 감사드립니다. 기존 MFC 확장 DLL을 C++/CLI로 Wrapping해서 C#에서 사용하고자 하고 있습니다.
    기존 DLL에서 parameter로 char[32]로 크기가 고정된 문자열을 받는다면 어떻게 marshaling을 해야하는지 궁금합니다.

  2. 내용중에
    marshal_context ctx;로만 할 경우 해당 행에서 Reentrance관련 오류가 발생합니다. MDA를 사용하지 않음으로 했더니, AccesViolation 오류가 발생하구요.
    결국 marshal_context^ ctx = gcnew marshal_cotext();로 하여 진행 하였습니다.

  3. Choyee // 파라미터가 char[32]로 되어 있는 경우는 마셜링 유틸함수에서는 지원하지 않으니 수작업을 하셔야 될 것 같습니다. 그리고 MDA 사용하지 않음이 뭔지 저는 잘 모르겠네요^^;;. 참고로 C++/CLI는 지역 변수의 경우는
    marshal_context ctx; 코딩하면 컴파일러가 자동으로
    marshal_context^ ctx = gcnew marshal_cotext(); 만들어주기 때문에 gcnew를 하지 않아도 됩니다(정확하게는 컴파일러가 코드를 만들어주기 때문에 사용하지 않는건 아니죠)