Pemrograman dengan CComBSTR (ATL)
CComBSTR kelas ATL menyediakan pembungkus di sekitar jenis data BSTR. Meskipun CComBSTR
merupakan alat yang berguna, ada beberapa situasi yang perlu diwaspadai.
Masalah Konversi
Meskipun beberapa CComBSTR
metode akan secara otomatis mengonversi argumen string ANSI menjadi Unicode, metode akan selalu mengembalikan string format Unicode. Untuk mengonversi string output kembali ke ANSI, gunakan kelas konversi ATL. Untuk informasi selengkapnya tentang kelas konversi ATL, lihat Makro Konversi String ATL dan MFC.
Contoh
// 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);
Jika Anda menggunakan string literal untuk memodifikasi CComBSTR
objek, gunakan string karakter lebar untuk mengurangi konversi yang tidak perlu.
// The following converts the ANSI string to Unicode
CComBSTR bstr1("Test");
// The following uses a Unicode string at compile time
CComBSTR bstr2(L"Test");
Masalah Cakupan
Seperti halnya kelas yang bereaksi baik, CComBSTR
akan membebaskan sumber dayanya ketika keluar dari cakupan. Jika fungsi mengembalikan penunjuk ke CComBSTR
string, ini dapat menyebabkan masalah, karena penunjuk akan mereferensikan memori yang telah dibebaskan. Dalam kasus ini, gunakan metode , seperti yang ditunjukkan Copy
di bawah ini.
Contoh
// 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);
}
Secara eksplisit Membebaskan Objek CComBSTR
Dimungkinkan untuk secara eksplisit membebaskan string yang terkandung dalam CComBSTR
objek sebelum objek keluar cakupan. Jika string dibesarkan, CComBSTR
objek tidak valid.
Contoh
// 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.
Menggunakan Objek CComBSTR dalam Perulangan
CComBSTR
Karena kelas mengalokasikan buffer untuk melakukan operasi tertentu, seperti +=
operator atau Append
metode, tidak disarankan agar Anda melakukan manipulasi string di dalam perulangan yang ketat. Dalam situasi ini, CStringT
memberikan performa yang lebih baik.
Contoh
// This is not an efficient way to use a CComBSTR object.
CComBSTR bstrMyString;
HRESULT hr;
while (bstrMyString.Length() < 1000)
hr = bstrMyString.Append(L"*");
Masalah Kebocoran Memori
Meneruskan alamat yang diinisialisasi CComBSTR
ke fungsi sebagai parameter [out] menyebabkan kebocoran memori.
Dalam contoh di bawah ini, string yang dialokasikan untuk menahan string "Initialized"
bocor saat fungsi MyGoodFunction
menggantikan string.
CComBSTR bstrLeak(L"Initialized");
HRESULT hr = MyGoodFunction(&bstrLeak);
Untuk menghindari kebocoran, panggil Empty
metode pada objek yang ada CComBSTR
sebelum meneruskan alamat sebagai parameter [out ].
Perhatikan bahwa kode yang sama tidak akan menyebabkan kebocoran jika parameter fungsi [ masuk, keluar].