다음을 통해 공유


TN059: MBCS/유니코드 MFC 변환 매크로 사용합니다.

[!참고]

온라인 설명서의을 처음 포함 되었습니다 때문 다음 기술 참고 업데이트 되지 않았습니다.따라서 일부 절차 및 항목 오래 되었거나 잘못 된 수 있습니다.최신 정보는 온라인 설명서 색인에서 관심 있는 주제에 대해 검색 하는 것이 좋습니다.

이 주석은 AFXPRIV에서 정의 되는 MBCS/유니코드 변환 된 매크로 사용 하는 방법을 설명 합니다.H.이러한 매크로 응용 프로그램 처리를 직접 OLE api 또는 어떤 이유로 자주 해야 하는 경우 유니코드와 MBSC 간을 변환할 가장 유용 합니다.

개요

MFC 3.x에서는 특별 한 DLL 사용 되었습니다 (MFCANS32.DLL) OLE 인터페이스를 호출한 경우 유니코드와 MBSC 간을 자동으로 변환 합니다.이 DLL이 OLE 응용 프로그램의 OLE Api 및 인터페이스 MBCS 처럼 항상 유니코드 됩니다 경우에 쓸 수 있는 거의 투명 레이어 되었습니다 (Macintosh에서 제외).이 레이어를 편리 하 게 했지만에서 Win16 win32로 이식 해야는 신속 하 게 응용 프로그램을 허용 하 고 (MFC, Microsoft Word, Microsoft Excel 및 VBA은이 기술을 사용 하는 Microsoft 응용 프로그램의 일부) 열었을 현저한 성능 적중.이러한 이유로 MFC 4.x이이 DLL을 사용 하지 않는 및 대신 바로 유니코드 OLE 인터페이스를 설명 합니다.이렇게 하려면 MFC OLE 인터페이스를 호출 하면 MBCS 유니코드로 변환 하 고 종종 OLE 인터페이스를 구현 하는 경우 유니코드에서 MBCS로를 변환 해야 합니다.이 쉽고 효율적으로 처리 하는 많은 매크로가이 변환을 쉽게 만들었습니다.

이러한 일련의 매크로 작성 하는 가장 큰 문제 중 하나는 메모리 할당입니다.문자열에서 변환할 수 없습니다 때문에 변환 된 결과 저장할 새 메모리를 할당 해야 합니다.다음과 비슷한 코드로 수행 된 수 있습니다.:

// we want to convert an MBCS string in lpszA
int nLen = MultiByteToWideChar(CP_ACP, 0,lpszA, -1, NULL, NULL);
LPWSTR lpszW = new WCHAR[nLen];
MultiByteToWideChar(CP_ACP, 0, 
   lpszA, -1, lpszW, nLen);
// use it to call OLE here
pI->SomeFunctionThatNeedsUnicode(lpszW);
// free the string
delete[] lpszW;

이 방법은 문제가 많은.주요 문제는 많은 양의 코드를 작성, 테스트 및 디버깅할 수 있는지입니다.간단한 함수 호출, 있던 것 지금 훨씬 더 복잡 한입니다.또한 있을 중요 한 런타임 오버 헤드가 이렇게.메모리 힙에 할당 하 고 변환을 수행 될 때마다 해제 해야 합니다.마지막으로 위의 코드에 적절 한 필요 #ifdefs (는 이러한 변환을 수행할 필요가) 유니코드 및 Macintosh 빌드에 추가 되었습니다.

우리 함께 위로 솔루션 소스 코드는 1) 마스크의 차이 다양 한 플랫폼 및 2) 사용으로 효율적인 메모리 할당 체계 및 3)는 기존에 삽입 하기 쉬운 몇 가지 매크로 만드는 것입니다.정의 중 하나를 예는 다음과 같습니다.

#define A2W(lpa) (\
    ((LPCSTR)lpa == NULL) ? NULL : (\
          _convert = (strnlen(lpa)+1),\
        AfxA2WHelper((LPWSTR) alloca(_convert*2), 
      lpa, _convert)\
    )\
)

이 및 위의 코드 대신 매크로 사용 하는 훨씬 간단 하 게 다음과 같습니다.

// use it to call OLE here
USES_CONVERSION;
pI->SomeFunctionThatNeedsUnicode(T2OLE(lpszA));

추가 호출이 변환 필요 하지만 매크로 사용 하 여 간단 하 고 효과적인 것입니다.

각 매크로의 구현에서 스택 대신 힙의 메모리를 할당할 수 _alloca() 함수를 사용 합니다.스택에서 메모리를 할당 하 여 힙에 메모리를 할당 하는 보다 훨씬 빠르게 수행 됩니다 및 함수가 종료 될 때 메모리가 자동으로 해제 됩니다.또한 매크로 호출을 방지 MultiByteToWideChar (또는 WideCharToMultiByte) 두 번 이상.이 필요한 것 보다 약간 더 많은 메모리를 할당 하 여 수행 됩니다.MBC에 최대 하나의 변환 한다는 것을 알고 WCHAR 와 각 WCHAR 우리는 최대 두 개의 MBC 바이트를 갖게 됩니다.할당 하지만 항상 충분히가 조금 넘는 필요 하 여 둘째 변환이 두 번째 호출을 처리 하는 변환 함수 호출을 피할 수 있습니다.도우미 함수 호출이 AfxA2Whelper 변환을 수행 하기 위해 수행 해야 하는 인수 푸시 수가 줄어듭니다 (호출 하는 경우이 코드에서는 작은 보다 결과 MultiByteToWideChar 직접).

저장 하기 위해에 공간이 매크로 임시 길이, 변환 매크로의 각 함수는이 수행 하는 _convert 라는 로컬 변수를 사용 하 여 작업을 선언 하는 것이 필요 합니다.이 호출 하 여 수행 되는 USES_CONVERSION 위의 예에서 볼 수 있듯이 매크로.

일반 변환 매크로 OLE 특정 매크로입니다.이러한 두 가지 다른 매크로 설정 아래에 나와 있습니다.모든 매크로 AFXPRIV에 상주합니다.H.

일반 변환 매크로

일반 변환 매크로 내부 메커니즘을 형성합니다.매크로 예제와 A2W, 이전 섹션에서 나온 이런 "일반" 매크로 하나입니다.이 OLE에 특별히 관련 되지 않았습니다.제네릭 매크로 집합이 다음과 같습니다.

A2CW      (LPCSTR) -> (LPCWSTR)
A2W      (LPCSTR) -> (LPWSTR)
W2CA      (LPCWSTR) -> (LPCSTR)
W2A      (LPCWSTR) -> (LPSTR)

텍스트 변환을 수행 하는 것 외에 가지 매크로 변환에 대 한 도우미 함수 TEXTMETRIC, DEVMODE, BSTR, 및 OLE 문자열을 할당 합니다.이 매크로 구분이 논의의 범위를 벗어납니다 – AFXPRIV를 참조 하십시오.이러한 매크로 대 한 자세한 내용은 H입니다.

OLE 변환 매크로

OLE 변환 매크로 함수를 처리 하기 위해 특별히 설계 된 OLESTR 문자.OLE 헤더를 검사 하는 경우에 많은 참조가 나타납니다 LPCOLESTROLECHAR.이러한 형식은 OLE 인터페이스를 플랫폼에 특정 하지 않은 방식으로 사용 하는 문자 유형을 참조 하는 데 사용 됩니다.OLECHAR 매핑합니다 char 에서 Win16 및 Macintosh 플랫폼 및 WCHAR win32에서.

수를 유지 하기 위해 # ifdef 지시문에는 MFC 코드를 최소한으로 각 변환에 대해 비슷한 매크로 까는 OLE 문자열 관련.다음 매크로 가장 일반적으로 사용 됩니다.

T2COLE   (LPCTSTR) -> (LPCOLESTR)
T2OLE   (LPCTSTR) -> (LPOLESTR)
OLE2CT   (LPCOLESTR) -> (LPCTSTR)
OLE2T   (LPCOLESTR) -> (LPCSTR)

다시는 비슷한 매크로 작업 TEXTMETRIC, DEVMODE, BSTR, 및 OLE 문자열을 할당 합니다.AFXPRIV를 참조 하십시오.자세한 내용은 H.

기타 고려 사항

매크로에서 반복 되는 루프를 사용 하지 않습니다.예를 들어, 다음과 같은 종류의 코드를 작성 하지 않을 수 있습니다.

void BadIterateCode(LPCTSTR lpsz)
{
   USES_CONVERSION;
   for (int ii = 0; ii < 10000; ii++)
      pI->SomeMethod(ii, T2COLE(lpsz));
}

메가바이트의 문자열의 어떤 내용에 따라 스택에 메모리를 할당 하는 위의 코드 발생할 수 lpsz 입니다!또한 루프의 각 반복에 대 한 문자열을 변환 하는 데 시간이 걸리는.대신, 이러한 상수 변환의 루프 밖으로 이동 합니다.

void MuchBetterIterateCode(LPCTSTR lpsz)
{
   USES_CONVERSION;
   LPCOLESTR lpszT = T2COLE(lpsz);
   for (int ii = 0; ii < 10000; ii++)
      pI->SomeMethod(ii, lpszT);
}

다음은 문자열 상수 이면 메서드를 호출 하는 함수에 캡슐화 합니다.이렇게 변환 버퍼 때마다 해제 될 수 있습니다.예를 들면 다음과 같습니다.

void CallSomeMethod(int ii, LPCTSTR lpsz)
{
   USES_CONVERSION;
   pI->SomeMethod(ii, T2COLE(lpsz));
}

void MuchBetterIterateCode2(LPCTSTR* lpszArray)
{
   for (int ii = 0; ii < 10000; ii++)
      CallSomeMethod(ii, lpszArray[ii]);
}

절대로 반환 값 반환 하기 전에 데이터의 복사본을 만드는 것을 의미 하지 않으면 결과 매크로 중 하나를 반환 합니다.예를 들어,이 코드는 잘못 된입니다.

LPTSTR BadConvert(ISomeInterface* pI)
{
   USES_CONVERSION;
   LPOLESTR lpsz = NULL;
   pI->GetFileName(&lpsz);
   LPTSTR lpszT = OLE2T(lpsz);
   CoMemFree(lpsz);
   return lpszT; // bad! returning alloca memory
}

위의 코드 대상에 값을 복사 하는 반환 값을 변경 하 여 해결할 수 있습니다.

CString BetterConvert(ISomeInterface* pI)
{
   USES_CONVERSION;
   LPOLESTR lpsz = NULL;
   pI->GetFileName(&lpsz);
   LPTSTR lpszT = OLE2T(lpsz);
   CoMemFree(lpsz);
   return lpszT; // CString makes copy
}

매크로 쉽고 간편한를 코드에 삽입할 수 있지만 위의 주의 사항에서 알 수 있듯이 사용할 때는 주의 해야 합니다.

참고 항목

기타 리소스

번호 기술 정보

범주별 기술 노트