ATL and MFC String Conversion Macros 사용 시 주의할 점
저장소/VC++출처 MSDN : https://msdn.microsoft.com/ko-kr/library/87zae4a3(v=vs.120).aspx
요약:
loop 내에서는 A2W 등의 ATL 3.0 매크로를 쓰지 마라. 스택 오버플로우 문제가 발생할 수 있다.
어쩔 수 없이 써야한다면 ATL 7.0 매크로(CA2WEX class 등)를 사용해야 한다.
ATL and MFC String Conversion Macros
ATL 7.0에는 기존 매크로에 비해 크게 향상된 여러 가지 새 변환 클래스와 매크로가 도입되었습니다.
새로운 문자열 변환 클래스 및 매크로 이름의 형식은 다음과 같습니다.
C SourceType 2[C]DestinationType[EX]
다음은 각 문자에 대한 설명입니다.
SourceType 및 DestinationType은 아래 테이블에 설명되어 있습니다.
[C]는 대상 형식이 상수여야 하는 경우 표시됩니다.
[EX]는 버퍼의 초기 크기가 템플릿 인수로 지정되어야 하는 경우 표시됩니다.
SourceType/DestinationType
설명
A
ANSI 문자열입니다.
W
유니코드 문자열입니다.
T
일반 문자열입니다. _UNICODE가 정의된 경우에는 W와 동일하며, 그렇지 않은 경우에는 A와 동일합니다.
OLE
OLE 문자열입니다. W와 동일합니다.
예를 들어 변환된 문자열을 변경하지 않고 유니코드 문자열에서 일반 문자열로 변환하려면 CW2CT를 사용합니다.
주의 |
---|
변환된 문자열이 64자 이하일 가능성이 높은 경우에는 CW2CTEX<64> 등의 EX 버전을 사용하여 스택에서 공간을 절약할 수 있습니다.
참고 |
---|
보안 정보 |
---|
이전 문자열 변환 매크로와 새로운 문자열 변환 클래스의 몇 가지 중요한 차이점은 다음과 같습니다.
이전 ATL 3.0 변환 매크로 | 새 ATL 7.0 변환 클래스 |
---|---|
스택에 메모리를 할당합니다. | |
함수가 종료되면 문자열이 해제됩니다. | 변수가 범위를 벗어나면 문자열이 해제됩니다. |
예외 처리기에서는 사용할 수 없습니다. | 예외 처리기에서 사용할 수 있습니다. |
보통 USES_CONVERSION을 정의해야 합니다. | USES_CONVERSION을 정의하지 않아도 됩니다. |
OLE의 의미가 OLE2ANSI 정의에 따라 달라집니다. | OLE는 항상 W와 동일합니다. |
//Example 1 // Convert LPCWSTR to LPCSTR. void ExampleFunction1(LPCWSTR pszW) { // Create an instance of CW2A, called pszA, // and initialize it with pszW. CW2A pszA(pszW); // pszA works like an LPCSTR, and can be used thus: ExampleFunctionA(pszA); // Note: pszA will become invalid when it goes out of scope. } // Example 2 // Use a temporary instance of CW2A. void ExampleFunction2(LPCWSTR pszW) { // Create a temporary instance of CW2A, // and initialize it with pszW. ExampleFunctionA(CW2A(pszW)); // Note: the temporary instance becomes invalid // after the execution of the statement above. } // Example 3 // Incorrect use of conversion macros. void ExampleFunction3(LPCWSTR pszW) { // Create a temporary instance of CW2A, // save a pointer to it and then delete // the temportary instance. LPCSTR pszA = CW2A(pszW); // The pszA in the following line is an invalid pointer, // as the instance of CW2A has gone out of scope. ExampleFunctionA(pszA); }
아래 코드는 효율적인 코드가 아닙니다.
LPCTSTR szr = CA2T(szReplaceFile);
ATL 3.0 매크로를 사용하면 다음 코드를 사용할 수 있습니다.
LPCTSTR szr = A2T(szReplaceFile);
아래 코드는
LPCTSTR szr = CA2T(szReplaceFile);
다음 코드 조각과 일치합니다.
LPCTSTR szr;
{
CA2T temp(szReplaceFile);
szr = temp.operator LPTSTR();
}
임시 개체가 제거되면 해당 임시 개체가 할당하고 캐스트 연산자에서 반환된 메모리도 제거되므로, szr의 값을 사용하면 원하는 결과를 얻을 수 없습니다.
대신 다음 코드를 사용합니다.
CA2T szr(szReplaceFile);
캐스트 연산자는 CA2T 개체를 LPCTSTR과 같이 표시합니다.
// Example 4 // Changing the size of the buffer. void ExampleFunction4(LPCWSTR pszW) { // Use a 16-character buffer. ExampleFunctionA(CW2AEX<16>(pszW)); }
아래에는 클래스의 생성자에 대해 코드 페이지를 두 번째 매개 변수로 지정하는 예가 나와 있습니다.
// Example 5 // Specifying the code page. void ExampleFunction5(LPCWSTR pszW) { // Convert to the Macintosh code page ExampleFunctionA(CW2A(pszW, CP_MACCP)); }
아래 테이블에 나와 있는 원래 텍스트 변환 매크로도 계속 사용할 수 있습니다.
A2BSTR | OLE2A | T2A | W2A |
A2COLE | OLE2BSTR | T2BSTR | W2BSTR |
A2CT | OLE2CA | W2CA | |
A2CW | OLE2CT | T2COLE | W2COLE |
A2OLE | OLE2CW | T2CW | W2CT |
A2T | OLE2T | T2OLE | W2OLE |
A2W | OLE2W | T2W | W2T |
이러한 매크로 사용을 위한 구문은 다음과 같습니다.
MACRONAME( string_address )
예를 들면 다음과 같습니다.
A2W(lpa);
따라서 A2W는 LPSTR을 LPWSTR로 변환하고 OLE2T는 LPOLESTR을 LPTSTR로 변환하는 식으로 변환이 수행됩니다.
적용되는 컴파일러 지시문 | T의 변경 결과 | OLE의 변경 결과 |
---|---|---|
없음 | A | W |
_UNICODE | W | W |
OLE2ANSI | A | A |
W | A |
void StringFunc(LPSTR lpsz) { USES_CONVERSION; LPWSTR x = A2W(lpsz); // Do something with x wprintf_s(L"x is %s", x); }
'저장소 > VC++' 카테고리의 다른 글
across DLL boundaries (cross-DLL problem) (0) | 2016.04.08 |
---|---|
VS2012의 tuple (0) | 2014.09.17 |
[펌] shlwapi 의 파일 경로 관련 API 모음 (0) | 2014.08.13 |
strftime format 좀 기억하자! (0) | 2014.08.08 |
SQLite - Syntax (0) | 2014.05.27 |