Ansi, Unicode, UTF-8 문자열 상호 변환

- 안시, 유니코드


* ATL 3.0(vc6) 이나 ATL7.0(Visual Studio 2003) 사용

    필요헤더 : AtlConv.h
    함수 이름 포함글자 의미
A - ANSI 문자열
W - 유니코드 문자열
T - 일반 문자열 (TEXT, _T("") ).
OLE - OLE 문자열


* ATL3.0 문자열 변환 매크로 리스트

A2BSTR

OLE2A

T2A

W2A

A2COLE

OLE2BSTR

T2BSTR

W2BSTR

A2CT

OLE2CA

T2CA (사용 되지 않음. Use T2CA_EX or CT2CA instead.)

W2CA

A2CW

OLE2CT

T2COLE

W2COLE

A2OLE

OLE2CW

T2CW

W2CT

A2T

OLE2T

T2OLE

W2OLE

A2W

OLE2W

T2W

W2T


- 방법
USES_CONVERSION;//쓰기전에 일단 사용, ATL7에서는 필요 없음
char *pAnsi = "안시";
TCHAR *pStr = A2T(pAnsi);

//스택에 메모리가 할당되므로 별도 메모리작업이 필요없다

//함수 종료시 메모리 해제


//================================
// UTF8 로 변환(직접 코딩 소스)
// ATL식 함수
//Unicode -> UTF8 변환
LPSTR W2U8Helper(LPSTR lpaOut, LPCWSTR lpw, int nChars, UINT acp)
{
    ASSERT(lpw != NULL);
    ASSERT(lpaOut != NULL);
    if (lpaOut == NULL || lpw == NULL)
        return NULL;

    *lpaOut = '\0';
    int ret = WideCharToMultiByte(CP_UTF8, 0, lpw, -1, lpaOut, nChars, NULL, NULL);
    if(ret == 0)
    {
        ASSERT(FALSE);
        return NULL;
    }
    return lpaOut;
}


//Ansi(Multi Byte) -> UTF-8 변환
LPSTR  A2U8Helper(LPSTR lpu8Out,    LPCSTR lpa,    int nChars, UINT acp)
{   
    ASSERT(lpa != NULL);
    ASSERT(lpu8Out != NULL);
    if (lpu8Out == NULL || lpa == NULL)
        return NULL;
   
    nChars++;

    // MB -> Uni
    LPWSTR wcTemp = (LPWSTR)alloca((nChars)*2);
    MB2WC(lpa, wcTemp, (nChars+1)*2);

    //Uni -> UTF8
    *lpu8Out = '\0';
    int ret = WideCharToMultiByte(CP_UTF8, 0, wcTemp, -1, lpu8Out, nChars*3, NULL, NULL);
    if(ret == 0)
    {
        ASSERT(FALSE);
        return NULL;
    }
    return lpu8Out;
}


//UTF-8 -> Unicode 변환
LPWSTR  U8toWHelper( LPWSTR lpwOut, LPCSTR lpa, int nChars, UINT acp)
{   
    ASSERT(lpa != NULL);
    ASSERT(lpwOut != NULL);
    if (lpwOut == NULL || lpa == NULL)
        return NULL;
   
    nChars++;

    // UTF8 -> Uni
    *lpwOut = '\0';
    int ret = MultiByteToWideChar(CP_UTF8, 0, lpa ,  -1 , lpwOut, nChars*2);//UTF8 -> Unicode   
    if(ret == 0)
    {
        ASSERT(FALSE);
        return NULL;
    }
    return lpwOut;
}


//UTF-8 -> Multi Byte 변환
LPSTR  U8toAHelper( LPSTR lpaOut, LPCSTR lpau8, int nChars, UINT acp)
{   
    ASSERT(lpaOut != NULL);
    ASSERT(lpau8 != NULL);
    if (lpau8 == NULL || lpaOut == NULL)
        return NULL;
   
    nChars++;

    // UTF8 -> Uni
    LPWSTR wcTemp = (LPWSTR)alloca( nChars*2);
    if( !UTF8toWC( lpau8, wcTemp, nChars*2) ) return 0;

    // Uni -> Multibyte
    *lpaOut = '\0';
    int ret = WideCharToMultiByte(CP_ACP, 0, wcTemp ,  -1 , lpaOut, nChars*2,0,0);//UTF8 -> Unicode       
    if(ret == 0)
    {
        ASSERT(FALSE);
        return NULL;
    }
    return lpaOut;
}

//================================
// ATL식 사용을 위한 매크로
#define USES_CONVERSION2 int _convert2 = 0; UINT _acp2 = CP_ACP ;  LPCWSTR _lpw2 = NULL; LPCSTR _lpa2 = NULL;

//Unicode -> UTF-8
#define W2U8(lpw) (\
    ((_lpw2 = lpw) == NULL) ? NULL : (\
        (_convert2 = (WideCharToMultiByte(CP_UTF8, 0, _lpw2, -1, 0,0,0,0)+1), \
        (_convert2>INT_MAX/2) ? NULL : \
        W2U8Helper((LPSTR) alloca(_convert2*sizeof(WCHAR)), _lpw2, _convert2*sizeof(WCHAR), _acp2))))

#define A2U8(lpa) (\
    ((_lpa2 = lpa) == NULL) ? NULL : (\
        _convert2 = (lstrlenA(_lpa2)+1),\
        (INT_MAX/2<_convert2)? NULL :  \
        A2U8Helper((LPSTR) alloca(_convert2*3), _lpa2, _convert2, _acp2)))//한글은 3바이트를 차지함

#define U8toW(lpa) (\
    ((_lpa2 = lpa) == NULL) ? NULL : (\
        _convert2 = (lstrlenA(_lpa2)+1),\
        (INT_MAX/2<_convert2)? NULL :  \
        U8toWHelper((LPWSTR) alloca((_convert2+1)*2), _lpa2, _convert2, _acp2)))

#define U8toA(lpa) (\
    ((_lpa2 = lpa) == NULL) ? NULL : (\
        _convert2 = (lstrlenA(_lpa2)+1),\
        (INT_MAX/2<_convert2)? NULL :  \
        U8toAHelper((LPSTR) alloca((_convert2+1)), _lpa2, _convert2, _acp2)))
//====================================

참고 : http://msdn.microsoft.com/ko-kr/library/87zae4a3.aspx

ALT 3.0 과 ATL 7.0 차이 비교

기존 ATL 3.0 매크로 변환

새 ATL 7.0 변환 클래스

스택에 메모리를 할당합니다.

작은 문자열은 스택, 큰 문자열은  힙에 메모리 할당

문자열은 함수가 종료 될 때 해제 됩니다.

문자열은 변수가 범위를 벗어날 때 해제 됩니다.

예외 처리기에서 사용할 수 없습니다.

예외 처리기에서 사용할 수 있습니다.

루프에 사용 하기가 적합 하지 않습니다. 함수가 종료 될 때까지 메모리 사용이 증가 합니다.

루프를 지원합니다. 루프 내에서 반복될때 메모리가 해제됩니다

큰 문자열에 대한 것이 없습니다. 스택 공간에 제한 됩니다.

큰 문자열에도 문제가 없습니다. 

보통 USES_CONVERSION 정의가 필요 합니다.

USES_CONVERSION 정의가 필요없습니다

OLE의 의미가 OLE2ANSI 정의에 따라 달라 집니다.

OLE 는 W와 항상 같습니다.



반응형
Posted by codens