JHB의 프로그래밍 삽질기

[Visual C++] MultiByteToWideChar와 WidecharToMultiByte의 사용. 본문

PROGRAMMING/Win/MFC

[Visual C++] MultiByteToWideChar와 WidecharToMultiByte의 사용.

roter 2011.05.12 16:09

멀티바이트와 유니코드간의 교환!

문제 : LoadString이 이상한 문자를 읽어와요

rc의 StringTable에 있는 스트링을 읽어 오려면 기본적으로 LoadString을 사용 한다.
이 LoadString은,
rc파일의 인코딩이 한글(euc-kr, cp949)일 경우, 한글 윈도우에서 한글을 읽어 오는 것은 문제가 되지 않는다.
마찬가지로 인코딩이 일본어(shift_jis, cp932)일 경우, 일본 윈도우에서 일본어를 읽어 오는 것은 문제가 되지 않는다.

하지만 나는 매우 특별한 상황에 쳐하였으니 -.-;;
cp949로 인코딩 된 일본어(Japanese)를 일본OS에서 불러와야 하는 상황이 발생 하였다.

현재 사용하는 프로그램이 멀티바이트로 작성 돼 있다는 점을 명심하고,
우선 StringTable에 있는 것을 LoadString으로 읽었다.
읽었더니 바이트열이 cp949에 있는 그대로 읽히더라.
자, 그럼 이 녀석을 cp949인코딩 그대로 이용해서 유니코드로 바꾼 후 그 유니코드를 다시 cp932를 이용해서 멀티바이트로 바꿔주면, 안전하게 일본어 OS에서 표기 가능한 멀티바이트 인코딩으로 변환 될 것이다.


해당 소스를 보자.
p.s) WCHAR는 Wide Char로 보고, Wide Char는 걍 유니코드라고 쉽게 생각하자.

char szTest[1024];
int nRet = LoadString( hInstance, IDS_GNATHO_ERROR_LOAD_TRACKING_DATA_FIRST, szTest, 1024 );
CString strOriginal = LoadString( IDS_GNATHO_ERROR_REGISTRATION_FIRST );

char *pszSrc = strOriginal.GetBuffer( strOriginal.GetLength() ); //char은 멀티바이트용 캐릭터를 담는다
WCHAR szBridge[200]; //WCHAR는 widechar용(유니코드용) 캐릭터를 담는다.
int nLen = MultiByteToWideChar( 949, 0, pszSrc, -1, NULL, NULL	); //5번째 인자에 NULL을 주면 함수의 리턴 값으로 
							//유니코드 변환에 필요한 길이 값이 리턴 된다.
MultiByteToWideChar( 949, 0, pszSrc, -1, szBridge, nLen ); //strSrc을 cp949인코딩을 따라서 유니코드로 변환한다.
//인자는 순서대로 다음을 의미한다.
//UINT CodePage : 코드페이지 949인코딩 사용, 
//DWORD dwFlags : 뭔지 모르지만 걍 0 적고, 
//LPCSTR lpMultiByteStr : 멀티바이트가 있는 소스의 char
//int cbMultiByte : -1을 적으면 멀티바이트 담긴 변수의 문장 길이 전체를 자동 계산해줘서 들어간다,
//LPWSTR lpWideCharStr : 유니코드를 담을 목적지
//int cchWideChar : 유니코드 변환 길이. 정말 중요하다. 제대로 적어야함

char szDest[200]; //유니코드를 다시 멀티바이트로 변환 한 것을 담을 변수
int a = 1; // 디폴트 스트링을 사용 할 것인지?
nLen = WideCharToMultiByte( 932, 0, szBridge, -1, NULL, 0, NULL, NULL, ); //5번째 인자에 NULL을 주면 함수의 리턴 값으로
							//멀티바이트 변환에 필요한 길이 값이 리턴 된다.
WideCharToMultiByte( 932, 0, szBridge, -1,szDest, nLen, "?", &a ); //932인코딩을 따라서 유니코드를 멀티바이트로 변환 한다.
//인자는 순서대로 다음을 의미한다.
//UINT CodePage : codepage 932인코딩을 사용
//DWORD dwFlags : 뭔지 모르지만 걍 0 적자
//LPCWSTR lpWideCharStr : 유니코드가 있는 소스의 WCHAR
//int cchWideChar : -1을 적으면 유니코드 담긴 변수의 문장 길이 전체를 자동 계산해줘서 들어간다.
//LPSTR lpMultiByteStr : 멀티바이트로 변환된 결과물이 담길 목적지
//int cbMultiByte : 결과물의 길이. 정말 중요하다. 제대로 적어야함
//LPCSTR lpDefaultChar : 만약 해당 인코딩에 없는 글짜를 발견 할 경우 해당 문자로 대체한다.
//LPBOOL lpUsedDefaultChar : lpDefaultChar를 사용 할 것인지?

CString strEnd = szDest;

위처럼 유니코드로 한번 바꿨다가 그를 그대로 932로 돌렸다.
위의 문제로 완벽하게 해결 한 것은 아니였지만.. 그대로 인코딩 변환을 시도했다는 점에서 매우 뜻깊었다 -.-;;

0 Comments
댓글쓰기 폼