상세 컨텐츠

본문 제목

[Visual Studio] Character Set Unicode vs MBCS

똑똑한 개발/C++

by 성댕쓰 2022. 4. 26. 22:05

본문

visual studio에 캐릭터 set을 정하는 옵션이 있다.

이 옵션은 문자열과 관련한 여러 개의 window api 정의를 바꾼다.

int MessageBoxA(HWND hWnd, const char* lpText, const char* lpCaption, unsigned int uType);
int MessageBoxW(HWND hWnd, const wchar_t* lpText, const wchar_t* lpCaption, unsigned int uType);

MessageBoxA는 코드 페이지 인코딩을 적용하는 char parameter를 사용하고,

MessageBoxW는 UTF-16 인코딩을 적용하는 wchar_t parameter를 사용한다.

#ifdef UNICODE
   #define MessageBox MessageBoxW
#else
   #define MessageBox MessageBoxA
#endif

UNICODE 문자 집합 선택하고 MessageBox를 사용하면 W버전을 사용하는 것이다.

 

window는 Unicode는 UTF-16 인코딩을 사용한다.

MBCS는 locale에 따라 다른 코드 집합을 사용한다. ex) cp949

 

UTF-8을 지원하는 프로그램을 만들기 위해선 항상 W버전 function을 사용해야 한다. 

 

MessageBoxA는 코드 페이지 인코딩을 적용하는 char parameter를 사용하고,
MessageBoxW는 UTF-16 인코딩을 적용하는 wchar_t parameter를 사용한다.

위 사실을 이용해 아래의 코드를 이해할 수 있었다.

 

// MarshalANSI1.cpp
// compile with: /clr
#include <iostream>
#include <stdio.h>

using namespace std;
using namespace System;
using namespace System::Runtime::InteropServices;

#pragma unmanaged

void NativeTakesAString(const char* p) {
   printf_s("(native) received '%s'\n", p);
}

#pragma managed

int main() {
   String^ s = gcnew String("sample string");
   IntPtr ip = Marshal::StringToHGlobalAnsi(s);
   const char* str = static_cast<const char*>(ip.ToPointer());

   Console::WriteLine("(managed) passing string...");
   NativeTakesAString( str );

   Marshal::FreeHGlobal( ip );
}

유니코드 기반인 managed 언어에서 string을 unmanaged char로 보내는 코드다. char로 받아야 하므로 managed String을 Ansi 함수(Marshal::StringToHGlobalAnsi)를 이용하여 변환하는 것을 볼 수 있다.

 

// MarshalUnicode1.cpp
// compile with: /clr
#include <iostream>
#include <stdio.h>
#include <vcclr.h>

using namespace std;

using namespace System;
using namespace System::Runtime::InteropServices;

#pragma unmanaged

void NativeTakesAString(const wchar_t* p) {
   printf_s("(native) received '%S'\n", p);
}

#pragma managed

int main() {
   String^ s = gcnew String("test string");
   pin_ptr<const wchar_t> str = PtrToStringChars(s);

   Console::WriteLine("(managed) passing string to native func...");
   NativeTakesAString( str );
}

unmanaged에서 Unicode로 String을 받는 상황이다. PtrToStringChars의 반환 값이 wchar_t인 것을 확인할 수 있다.

 

 

참조 : unicode - Difference between MBCS and UTF-8 on Windows - Stack Overflow

How to: Marshal Unicode Strings Using C++ Interop | Microsoft Docs

How to: Marshal ANSI Strings Using C++ Interop | Microsoft Docs

'똑똑한 개발 > C++' 카테고리의 다른 글

[boost] asio#2  (0) 2022.05.02
[boost] asio #1  (0) 2022.05.01
enable_shared_from_this  (0) 2022.04.22
lvalue, rvalue 알아보자  (0) 2021.05.29
condition_variable에 대해서  (0) 2021.05.29

관련글 더보기

댓글 영역