CComBSTR을 사용한 프로그래밍(ATL)
ATL 클래스 CComBSTR 은 BSTR 데이터 형식에 대한 래퍼를 제공합니다. CComBSTR
유용한 도구이지만 주의해야 하는 몇 가지 상황이 있습니다.
여러 CComBSTR
메서드가 ANSI 문자열 인수를 유니코드로 자동으로 변환하지만 메서드는 항상 유니코드 형식 문자열을 반환합니다. 출력 문자열을 ANSI로 다시 변환하려면 ATL 변환 클래스를 사용합니다. ATL 변환 클래스 에 대한 자세한 내용은 ATL 및 MFC 문자열 변환 매크로를 참조하세요.
// Declare a CComBSTR object. Although the argument is ANSI,
// the constructor converts it into UNICODE.
CComBSTR bstrMyString("Hello World");
// Convert the string into an ANSI string
CW2A szMyString(bstrMyString);
// Display the ANSI string
MessageBoxA(NULL, szMyString, "String Test", MB_OK);
문자열 리터럴을 사용하여 개체를 CComBSTR
수정하는 경우 와이드 문자열을 사용하여 불필요한 변환을 줄입니다.
// The following converts the ANSI string to Unicode
CComBSTR bstr1("Test");
// The following uses a Unicode string at compile time
CComBSTR bstr2(L"Test");
잘 동작하는 클래스 CComBSTR
와 마찬가지로 범위를 벗어나면 리소스를 해제합니다. 함수가 문자열에 대한 포인터를 반환하는 CComBSTR
경우 포인터가 이미 해제된 메모리를 참조하므로 문제가 발생할 수 있습니다. 이러한 경우 아래와 같이 메서드를 Copy
사용합니다.
// The wrong way to do it
BSTR * MyBadFunction()
{
// Create the CComBSTR object
CComBSTR bstrString(L"Hello World");
// Convert the string to uppercase
HRESULT hr;
hr = bstrString.ToUpper();
// Return a pointer to the BSTR. ** Bad thing to do **
return &bstrString;
}
// The correct way to do it
HRESULT MyGoodFunction(/*[out]*/ BSTR* bstrStringPtr)
{
// Create the CComBSTR object
CComBSTR bstrString(L"Hello World");
// Convert the string to uppercase
HRESULT hr;
hr = bstrString.ToUpper();
if (hr != S_OK)
return hr;
// Return a copy of the string.
return bstrString.CopyTo(bstrStringPtr);
}
개체가 범위를 벗어나기 전에 개체에 포함된 문자열을 CComBSTR
명시적으로 해제할 수 있습니다. 문자열이 해제되면 개체가 CComBSTR
유효하지 않습니다.
// Declare a CComBSTR object
CComBSTR bstrMyString(L"Hello World");
// Free the string explicitly
::SysFreeString(bstrMyString);
// The string will be freed a second time
// when the CComBSTR object goes out of scope,
// which is invalid.
클래스는 CComBSTR
연산자 또는 Append
메서드와 같은 특정 작업을 수행하기 위해 버퍼를 +=
할당하므로 타이트 루프 내에서 문자열 조작을 수행하지 않는 것이 좋습니다. 이러한 상황에서는 CStringT
더 나은 성능을 제공합니다.
// This is not an efficient way to use a CComBSTR object.
CComBSTR bstrMyString;
HRESULT hr;
while (bstrMyString.Length() < 1000)
hr = bstrMyString.Append(L"*");
초기화된 CComBSTR
주소를 [out] 매개 변수로 함수에 전달하면 메모리 누수가 발생합니다.
아래 예제에서는 함수 MyGoodFunction
가 문자열을 대체할 때 문자열 "Initialized"
을 보유하도록 할당된 문자열이 유출됩니다.
CComBSTR bstrLeak(L"Initialized");
HRESULT hr = MyGoodFunction(&bstrLeak);
누출을 방지하려면 주소를 [out] 매개 변수로 전달하기 전에 기존 CComBSTR
개체에서 메서드를 호출 Empty
합니다.
함수의 매개 변수 가 [in, out]인 경우 동일한 코드로 인해 누수가 발생하지 않습니다.