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

이 노트에서는 AFXPRIV에 정의 되는 MBCS/유니코드 변환에 대 한 매크로 사용 하는 방법을 설명 합니다.H. 이러한 매크로 응용 프로그램 거래 직접 OLE API 또는 어떤 이유로 자주 해야 하는 경우 유니코드와 MBCS 간의 변환에 가장 유용。

개요

MFC 3.x에서는 특별 한 DLL 사용 (MFCANS32.DLL) 자동으로 변환 유니코드와 MBCS 간의 OLE 인터페이스 호출 했다. 이 DLL은 쓸 마치 OLE Api 및 인터페이스 MBCS, 비록 그들은 항상 유니코드 OLE 응용 프로그램 허용 거의 투명 레이어 (macintosh의 경우 제외). 이 레이어는 편리 하 게 하는 동안 응용 프로그램을 Win32 win16에서 신속 하 게 포팅 수 허용 (MFC, Microsoft Word, Microsoft Excel 및 VBA는이 기술을 사용 하는 Microsoft 응용 프로그램의 일부 단지), 때로는 상당한 성능 했다 했다. 이러한 이유로 MFC 4.x이이 DLL을 사용 하지 않는 하 고 대신 유니코드 OLE 인터페이스에 직접 회담. 이렇게 하려면 MFC OLE 인터페이스를 호출 하는 경우 MBCS 유니코드 변환 해야 하 고 자주 OLE 인터페이스를 구현 하는 경우 유니코드에서 MBCS를 변환할 필요가 있다. 효율적이 고 쉽게이 처리 하기 위해 매크로 수가이 변환을 쉽게 만들어졌습니다.

매크로의 집합을 만드는 가장 큰 장애물 중 하나는 메모리 할당입니다. 장소에서 문자열을 변환할 수 없습니다, 때문에 변환된 결과 저장할 새 메모리를 할당 합니다. 이 코드는 다음과 유사 하 게 할 수 있습니다.:

/ / 우리 Lpsza에서 MBCS 문자열을 변환 하려면
int nLen = MultiByteToWideChar (CP_ACP, 0, lpszA,-1, NULL, NULL);
LPWSTR lpszW = 새로운 WCHAR [nLen];
MultiByteToWideChar (CP_ACP, 0, lpszA,-1, lpszW, nLen);
/ / 여기 OLE 호출을 사용 하는
pI-gt;SomeFunctionThatNeedsUnicode(lpszW);
/ / 문자열을 무료
lpszW 삭제(&G)

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

우리와 함께 온 솔루션 일부 매크로 1) 마스크 다양 한 플랫폼 및 2) 사용 하 여 효율적인 메모리 할당 구성표의 차이 및 3)은 기존에 삽입 쉽게 소스 코드를 만드는 것입니다. 여기 하나의 정의의 예가입니다.:

# define A2W(lpa) (\
 nbsp;? ((LPCSTR) lpa = = NULL)? NULL: (\
 ??      ? _convert (strlen (lpa) + 1) = \
 ?????? AfxA2WHelper((LPWSTR) alloca(_convert*2), lpa, _convert) \
 ?? )\
)(&N)

훨씬 간단 하 게는이 위의 코드 대신 매크로 등을 사용 하 여:

/ / 여기 OLE 호출을 사용 하는
USES_CONVERSION;
pI-gt;SomeFunctionThatNeedsUnicode(T2OLE(lpszA))(&G)

거기에 여분의 통화 변환 작업이 필요 하지만 매크로 사용 하는 간단 하 고 효과적인。

_Alloca() 함수를 사용 하 여 힙 대신 스택에서 메모리를 할당 하는 각 매크로의 구현. 스택에서 메모리를 할당 힙의 메모리 할당 보다 훨씬 더 빨리 그리고 메모리는 함수가 종료 될 때 자동으로 해제 됩니다. 또한, 매크로 MultiByteToWideChar (또는 WideCharToMultiByte)를 호출 하지 마십시오 번 이상. 이것은 필요한 것 보다 조금 더 많은 메모리를 할당 하 여 이루어집니다. 우리는 MBC 많아야 하나의 WCHAR 로 변환 됩니다 알고 각 WCHAR 에 대 한 우리 두 MBC 바이트의 최대 있을 것입니다. 보다 조금 더 필요 하지만 항상 충분히 할당 하 여 두 번째 변환 두 번째 호출을 처리 하기 위해 변환 함수를 호출 하는 피할 수 있습니다. AfxA2Whelper 도우미 함수를 호출 인수 되겠습니다 (이 인해 작은 코드 보다 그것 MultiByteToWideChar 을 직접 호출 하는 경우) 변환을 수행 하기 위해 수행 해야 하는 수를 줄여 줍니다.

하기 위해서는 공간을 매크로 대 한 저장 하는 임시 길이 그것은 변환 매크로 사용 하는 않는이 각 함수에 _convert 라는 지역 변수를 선언 하는 데 필요한. 이 예제에서 위에서 본 USES_CONVERSION 매크로 호출 하 여 이루어집니다.

거기에 일반적인 변환 매크로 및 OLE 특정 매크로. 이러한 두 가지 다른 매크로 세트는 아래에 설명 되어있습니다. 매크로의 모든 AFXPRIV에 상주 합니다.H。

일반 변환 매크로

일반 변환 매크로 기본 메커니즘을 형성합니다. 매크로 예제 및 구현 A2W, 이전 섹션 에서처럼 같은 하나의 "일반" 매크로입니다. 그것은 구체적으로 OLE에 아무 관계도 있다. 일반 매크로 설정 아래에 나열 됩니다.:

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

텍스트 변환 하 고, 게다가 거기에 매크로 및 TEXTMETRIC, DEVMODE, BSTR및 OLE 변환 하기 위한 도우미 함수 문자열을 할당 합니다. 이러한 매크로이 논의의 범위를 넘어-AFXPRIV를 참조 하십시오.이러한 매크로 대 한 자세한 내용은 H。

OLE 변환 매크로

OLE 변환 매크로 처리 OLESTR 문자를 기대 하는 기능을 위해 특별히 설계 되었습니다. OLE 헤더를 검사 하는 경우 LPCOLESTR 및 OLECHAR에 대 한 많은 참조가 나타납니다. 이러한 플랫폼에 특정 하지 않은 방식으로 OLE 인터페이스에 사용 되는 문자의 종류를 참조 하는 데 사용 됩니다. Win16 및 Macintosh 플랫폼에서 char 및 WCHAR 에서 Win32 OLECHAR 지도。

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

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

다시 TEXTMETRIC하 고 비슷한 매크로, DEVMODE, BSTR및 OLE 문자열을 할당 합니다. AFXPRIV를 참조 하십시오.더 많은 정보에 대 한 H。

기타 고려 사항

꽉 루프에서 매크로 사용 하지 마십시오. 예를 들어, 당신은 다음과 같은 종류의 코드를 작성 하려면:

void BadIterateCode(LPCTSTR lpsz)
{
USES_CONVERSION;
에 대 한 (int ii = 0; ii lt; 10000; ii + +)
pI-> SomeMethod (ii, T2COLE(lpsz));
}

위의 코드 문자열의 내용에 따라 스택에 메모리의 메가바이트 할당 될 수 있습니다 lpsz 입니다! nbsp; 또한 루프의 각 반복에 대 한 문자열을 변환 하는 시간이 걸립니다. 대신 루프의 밖으로 지속적인 변환 같은 이동(&N):

void MuchBetterIterateCode(LPCTSTR lpsz)
{
USES_CONVERSION;
LPCOLESTR lpszT = T2COLE(lpsz);
에 대 한 (int ii = 0; ii lt; 10000; ii + +)
pI-> SomeMethod (2, lpszT);
}

문자열 상수 경우, 함수에 메서드 호출을 캡슐화 합니다. 이것은 변환 버퍼 각 시간에 공간을 확보할 수 있게 됩니다. 예를 들어:

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

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

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

LPTSTR BadConvert(ISomeInterface* pI)
{
USES_CONVERSION;
LPOLESTR lpsz = NULL;
pI-gt;GetFileName(&lpsz);
LPTSTR lpszT = OLE2T(lpsz);
CoMemFree(lpsz);
반환 lpszT; / / 나쁜! alloca 메모리 반환
}

위의 코드는 값을 복사 하는 뭔가를 반환 값을 변경 하 여 해결 될 수 있습니다.:

CString BetterConvert(ISomeInterface* pI)
{
USES_CONVERSION;
LPOLESTR lpsz = NULL;
pI-gt;GetFileName(&lpsz);
LPTSTR lpszT = OLE2T(lpsz);
CoMemFree(lpsz);
반환 lpszT; / / CString 복사
}

매크로 코드에 삽입 하기 쉽고 사용 하기 쉬운 하지만 그들을 사용 하는 경우 주의 해야 위의 주의에서 말할 수 있는,。

기술 노트 번호로 |nbsp; 카테고리별 기술 노트(&N)

Index