다음을 통해 공유


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 명시적으로 해제할 수 있습니다. 문자열이 해제되면 개체가 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 개체 사용

클래스는 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]인 경우 동일한 코드로 인해 누수가 발생하지 않습니다.

참고 항목

개념
CStringT 클래스
wstring
문자열 변환 매크로