Source: http: //www.vckbase.com/document/viewdoc/ id = complete guide of 1096C string two - string wrapper class original:? Michael Dunn Author: Chengjie Sun ORIGINAL: CodeProject: The Complete Guide to C Strings, Part II Introduction Because the C language style string is easy to errors and is not easy to manage, the hacker even uses the possible buffer to overflow bug putting a C language style string as an attack target, so many string package classes appear. Unfortunately, in some occasions we don't know which string class should be used, do not know how to convert a C style string into a string package class. This article will introduce all string types that appear in Win32 API, MFC, STL, WTL, and Visual C Runturs. I will describe the usage of each class telling you how to create every class of objects and how to convert a class into other classes. Controlled strings and classes in Visual C 7 are Nish completed. In order to better benefit from this article, you have to understand different character types and encodings, which I have introduced in the first part. Rule # 1 of string Classes Using CAST to implement type conversion is a bad practice unless there is a document clearly indicating that this conversion can be used. The reason why I have written these two articles is some of the problems that are often encountered in string type conversions. When we use CAST to convert the string from type X to type z, we don't know why the code cannot work properly. A variety of string types, especially BSTR, almost no documents in any place, clearly indicate that Cast can be implemented with CAST. So I think some people may use CAST to implement type conversion and hope that this conversion will work properly. Unless the source string is a string package class that is explicitly specified to support the conversion operator, CAST does not do any conversion to the string. Use CAST for a constant string not to play any effect, so the following code: Void Somefunc (LPCWSTR WIDESTR);
Main ()
{
SomeFunc ((lpcwstr) "c: //foo.txt"); // Wrong!
} Will definitely fail. It can be compiled because the CAST operation will undo the type of compiler. However, compilation can pass and not explain the code correct. In the example below, I will indicate when CAST is using it. C-Style strings and typedefs As I mentioned in the first part, Windows APIs are defined with tchars. When compiling, it can be compiled as a MBCS or Unicode character based on whether you define _mbcs or _unicode. You can see the full description of tchar in the first part, here for convenience, I list the type of TypedEfs
TypeMeaningWCHARUnicode character (wchar_t) TCHARMBCS or Unicode character, depending on preprocessor settingsLPSTR string of char (char *) LPCSTRconstant string of char (const char *) LPWSTR string of WCHAR (WCHAR *) LPCWSTR constant string of WCHAR (const WCHAR *) LPTSTR string Of Tchar (Tchar *) LPCTSTSTSTANT STRING OF TCHAR (Const Tchar *) An additional character type is Oletype. It represents the type of character types used in the automation interface (such as Word that can make the interface of your document). This type is typically defined as WCHAR_T, however if you define the OLE2ANSI pre-processing tag, OLECHAR will be defined as a CHAR type. I know that there is no reason to define ole2ansi (after the MFC3, Microsoft is no longer used), so I will treat Olechar as Unicode characters from now. Here, some OLECHAR associated with OleChar, TypeDefs: Typemeaningolechar Unicode Character (Olechar *) LPcolestr Constant String of Olechar (Const Olechar *) has two strings and characters Macro definition of constants, they can make the same code for MBCS and Unicode Builds:
TYPEENING_T (X) Prepends L to the Literal in Unicode Builds.olestr (x) Prepends L to the Literal To Make It An LPColestr. In the document or routine, you will also see a lot of _t variants. There are four equivalent macro definitions, they are text, _text, __text and __t, they all serve as the same. Strings in COM - BSTR and Variant Many automation and COM interfaces use BSTR to define strings. There are several "traps" in BSTRS, so I use a separate part to illustrate it. BSTR is a mixed product of the Pascal-Style string (string length is explicitly pointed out) and the C-style string (the length of the string is to be calculated by looking for the endorse). A BSTR is a Unicode string that is pre-considered, and it has a 0-character as an end tag. Below is an example of a BSTR:
06 00 00 0042 006F 0062 0000 00 - Length - Bobeos Note how the length of the string is added to the string data. The length is DWORD type, saved the number of bytes contained in the string, but does not include the end tag. In this example, "Bob" contains three Unicode characters (excluding end compass), with a total of 6 bytes. The length of the string is pre-stored in advance so that when a BSTR is passed between the process or the computer, the COM library knows how much data needs to be transmitted. (On the other hand, a BSTR can store any data block, not just a character, and it can also include 0 characters embedded in the data. However, because the purpose of this article, I will not consider those situations). In C , a BSTR is actually a pointer to the first character in the string. It is defined as follows: bstr bstr = null; bstr = sysallocstring (l "hi bob!");
IF (null == BSTR)
// out of memory error
// use bstr here ...
Sysfreestring (BSTR); Nature, a wide variety of BSTR package classes to implement memory management. Another variable type used in the automation interface is Variant. It is used to pass data in a Typeless language, such as JScript, and VBScript. A Variant may contain many different types of data, such as long and idispatch *. When a Variant contains a string, the string is stored in a BSTR. When I talked about the Variant package class, I will introduce Variant. String packages have been described so far, I have already introduced a variety of strings. Below, I will explain the package. For each package class, I will show how to create an object and how to convert it into a C language style string pointer. C Language-style string pointer is the call of the API, or create a different string class object is often necessary. I don't introduce other operations provided by the string class, such as sorting and comparison. Repeat it, unless you know what the result code will do, otherwise do not blindly use CAST to implement type conversion. CRT provides class _BSTR_T _BSTR_T is a complete package class for BSTR, in fact it hides the underlying BSTR. It provides a variety of constructors and operators to access the underlying C language style string. However, _bstr_t has not accessed the operator of the BSTR itself, so a string of _BSTR_T types cannot be passed to a COM method as an output parameter. If you need a BSTR * parameter, use ATL class CCOMBSTR is relatively easy. A _BSTR_T string can pass a function that receives the parameter type BSTR, just because the following three conditions are simultaneously met. First, _bstr_t has a conversion function to WCHAR_T * conversion; secondly, for the compiler, because the BSTR definition, Wchar_T * and BSTR have the same meaning; third, _bstr_t is included in the form of Wchar_t * points to the form of BSTR Store the memory of the data. Therefore, even if there is no document description, _bstr_t can be converted to BSTR, which can still be performed normally. // conncture
_BSTR_T BS1 = "char string"; // construct from a lpcstr
_BSTR_T BS2 = L "Wide Char String"; // Construct from A LPCWSTR_BSTR_T BS3 = BS1; // Copy from ANOTHER _BSTR_T
_VARIANT_T V = "Bob";
_BSTR_T BS4 = V; // Construct from A _variant_t That Has A String
// extracting data
LPCSTR PSZ1 = BS1; // Automatic or Converts to MBCS String
LPCSTR PSZ2 = (LPCSTR) BS1; // Cast OK, Same As Previous Line
LPCWSTR PWSZ1 = BS1; // Returns The Internal Unicode String
LPCWSTR PWSZ2 = (LPCWSTR) BS1; // Cast OK, Same As Previous Line
BSTR BSTR = BS1.copy (); // Copies BS1, Returns It as a BSTR
// ...
SysfreeString (BSTR); Note _BSTR_T also provides conversion operators between char * and WCHAR_T *. This is a designed design, because even if they are a very quantitative string pointer, you must also use these pointers to modify the contents of the buffers they point to, because it will destroy the internal BSTR structure. _variant_t _variant_t is a complete package for Variant, which provides a lot of constructor and conversion functions to operate a large number of data types that variant may contain. Here, I will only introduce the operation related to the string. // conncture
_VARIANT_T V1 = "char string"; // Construct from a lpcstr
_VARIANT_T V2 = L "Wide Char String"; // Construct from A LPCWSTR
_BSTR_T BS1 = "Bob";
_VARIANT_T V3 = BS1; // Copy from A _BSTR_T OBJECT
// extracting data
_BSTR_T BS2 = V1; // Extract Bstr from The Variant
_BSTR_T BS3 = (_BSTR_T) V1; // Cast OK, Same AS Previous Line Note: If the type conversion cannot be executed, _variant_t method can throw an exception, so you should prepare the capture _com_error exception. It should also be noted that there is no direct conversion from a _variant_t variable to an MBCS string. You need to create a temporary _BSTR_T variable, use another string class that provides Unicode to MBCS or use an ATL conversion macro. Unlike _BSTR_T, a _variant_t variable can be passed directly to a COM method as a parameter. _variant_t inherits from the Variant type, so passing a _variant_t to replace the Variant variable is allowed by the C language. STL class STL has only one string class, Basic_String. A Basic_String manages a string array of 0 to do a finish. The type of characters is the Basic_String Waitemic parameters. In general, a Basic_String type variable should be treated as an opaque object. You can get a read-only pointer to the internal buffer, but any write operation must use the operations and methods of Basic_String. Basic_string has two predefined types: a string type containing char and WString types containing Wchar_T. There is no built-in type of TCHAR here, but you can use the code listed below. // SpecializationStypedEf Basic_String
Tstring; // string of tchars
// conncture
String str = "char string"; // construct from a lpcstr
WString Wstr = L "Wide Char String"; // Construct from A LPCWSTR
Tstring TSTR = _t ("tchar string"); // construct from a lpctstr
// extracting data
LPCSTR PSZ = Str.c_Str (); // Read-Only Pointer to Str ''s Buffer
LPCWSTR PWSZ = WSTR.C_STR (); // Read-Only Pointer to WSTR ''s Buffer
LPCTSTR PTSZ = TSTR.C_STR (); // Read-Only Pointer to Tstr ''s Buffer
Unlike _BSTR_T, a Basic_String variable cannot be directly converted between character sets. However, you can pass the pointer returned by C_STR () to another class constructor (if this class constructor accepts this character type). For example: // eXample, construct_bstr_t from basic_string
_BSTR_T BS1 = Str.c_Str (); // Construct A _BSTR_T from A LPCSTR
_BSTR_T BS2 = WSTR.C_STR (); // Construct A _BSTR_T from a lpcwstr ATL class CCOMBSTR CCOMBSTR is a BSTR package class in ATL, which is useful in some cases more than _bstr_t. The most attention is that CCOMBSTR allows access to the underlying BSTR, which means that you can pass a CCOMBSTR object to the COM method. CCOMBSTR objects can automatically manage BSTR memory for your automatic memory. For example, suppose you want to call the method of the interface below: // Sample Interface: Struct ISTUFF: Public IUNKNOWN
{
// Boilerplate COM stuff omitted ...
STDMETHOD (SETTEXT) (BSTR BSTEXT);
STDMETHOD (BSTER * PBSTEXT);
}; CCOMBSTR has an operator -bstr method, so it can be directly transmitted to the SetText () function. There is another operation - &, this operator returns a BSTR *. So, you can use the & operator to a CCOMBSTR object, then pass it to a function that requires the BSTR * parameter. CCOMBSTR BS1;
CCOMBSTR BS2 = "New TEXT";
Pstuff-> GetText (& BS1); // OK, Takes Address of Internal BSTR
Pstuff-> setText (BS2); // OK, Calls BSTR Converter
PSTUFF-> SetText ((BSTR) BS2); // Cast OK, Same As Previous Line CCOMBSTR has a similar constructor similar to _bstr_t, but there is no built-in function to convert to MBCS string. Therefore, you need to use an ATL conversion macro. // conncture
CCOMBSTR BS1 = "char string"; // Construct from A LPCSTR
CCOMBSTR BS2 = L "Wide Char String"; // Construct from A LPCWSTR
CCOMBSTR BS3 = BS1; // Copy from another CCOMBSTR
CCOMBSTR BS4;
BS4.LoadString (IDS_SOME_STR); // load string from String Table
// extracting data
BSTR BSTR1 = BS1; // Returns Internal BSTR, But Don' '' '' in i!
BSTR BSTR2 = (BST) BS1; // Cast OK, Same As Previous Line
BSTR BSTR3 = BS1.copy (); // Copies BS1, Returns IT As A BSTR
BSTR BSTR4;
BSTR4 = BS1.DETACH (); // BS1 NO LONGER MANAGES ITS BSTR
// ...
Sysfreestring (BSTR3);
Sysfreestring (BSTR4); Note Using the drop () method in the previous example. After calling this method, the CCOMBSTR object will no longer manage its BSTR string or its corresponding memory. This is why BSTR4 needs to call sysfreestring (). Do a supplementary note: The overloaded & operator means you can't use CCOMBSTR variables directly in some STL containers, such as List. Container Requirements The set of operators returns a pointer to the class contained in the container, but returning to the CCOMBSTR variable is BSTR * instead of ccombstr *. However, there is an ATL class to solve this problem, this class is CADAPT. For example, you can declare a ccombstr's list: std :: list
Ccomvariant V2 = L "Wide Char String"; // Construct from A LPCWSTR
CCOMBSTR BS1 = "BSTR BOB";
CCOMVARIANT V3 = (BSTR) BS1; // Copy from A BSTR
// extracting data
CCOMBSTR BS2 = V1.BSTRVAL; // Extract Bstr from The Variant is unlike _variant_t, there is no provider of various types of conversion operators that are included in Variant. As mentioned above, you must directly access Variant's members and make sure this Variant variable saves your expectations. If you need to convert a CCOMVARIANT type data into a BSTR type data, you can call the ChangeType () method. Ccomvariant v4 = ... // init v4 from Somewhere
CCOMBSTR BS3;
IF (succeeded (v4.changetype)))
BS3 = V4.BSTRVAL; like _variant_t, CCOMVARIANT does not provide a conversion operation to the MBCS string. You need to create an intermediate variable of _BSTR_T type, use another string class that provides from Unicode to MBCS, or uses an ATL conversion macro.
ATL conversion macro ATL: Conversion macro is a very convenient way of conversion between various character encodings, and they look very useful when the function is called. The name of the ATL conversion macro is named after the following mode [Source Type] 2 [New Type] or [Source Type] 2C [New Type]. According to the conversion result of the macro of the second form, the conversion result is a constant pointer ("C" in the corresponding name). Various types of abbreviations are as follows: A: MBCS String, Char * (a for ANSI)
W: unicode string, wchar_t * (w for wide) T: tchar string, tchar *
OLE: OLECHAR STRING, OLECHAR * (in Practice, Equivalent to W)
BSTR: BSTR (Used as The Destination Type Only) So, the W2A () macro converts a Unicode string into an MBCS string. The T2CW () macro turns a TCHAR string into a Unicode string constant. In order to use these macros, you need to include an ATLCONV.H header file. You can even use this header file in a non-ATL project to use the macros defined because this header file is independent of the other parts of the ATL, and does not require a _Module global variable. When you use the conversion macro in a function, you need to put the Uses_Conversion macro in the beginning of the function. It defines some local variables required to convert macros. When the purpose type of the conversion is in addition to other types other than the BSTR, the converted string is in the stack. So, if you want the life cycle of the string than the current function, you need to copy this string to other string classes. When the purpose is BSTR, the memory will not be automatically released, you must assign the return value to a BSTR variable or a BSTR package class to avoid memory leakage. Here is some examples of various conversion macros: // functions taking various strings:
Void foo (LPCWSTR WSTR);
Void Bar (BSTR BSTR);
// functions return strings:
Void Baz (BSTR * PBSTR);
#include
Main ()
{
Using std :: string;
Uses_conversion; // Declare localis buy by the atl macros
// EXAMPLE 1: Send An Mbcs String to foo ()
LPCSTR psz1 = "bob";
String str1 = "bob";
FOO (A2CW (PSZ1));
FOO (A2CW (str1.c_str ()));
// EXAMPLE 2: Send a MBCS and Unicode String to bar ()
LPCSTR PSZ2 = "bob";
LPCWSTR WSZ = L "BOB";
BSTR BS1;
CCOMBSTR BS2;
BS1 = A2BSTR (PSZ2); // Create A BSTR
BS2.attach (W2BSTR (WSZ)); // Ditto, Assign to a ccombstr
BAR (BS1);
BAR (BS2);
Sysfreestring (BS1); // Free BS1 MEMORY
// no need to free bs2 Since CCOMBSTR WILL DO IT for US.
// EXAMPLE 3: Convert the BSTR RETURNED BY baz ()
BSTR BS3 = NULL;
String str2;
Baz (& BS3); // baz () Fills in BS3
STR2 = W2CA (BS3); // convert to an MBCS String
Sysfreestring (BS3); // Free BS3 Memory
} As you can see, when you have a string of the parameter type required by the function, it is very convenient to use these conversion macros. MFC Class CString Because an object of an MFC CString class contains characters of TCHAR types, the exact character type depends on the preprocessing symbol you defined. Generally speaking, CString is very similar to STL String, which means you have to use it as an opaque object, and can only use the method provided by cstring to modify the CString object. CString has the advantage of String: CString has a constructor that receives two strings of MBCS and Unicode, which also has an LPCTSTR converter, so you can pass the CString object directly to a function that receives LPCTSTR without calling C_STR () function. // conncture
CString S1 = "char string"; // Construct from A LPCSTR
CString S2 = L "Wide Char String"; // Construct from A LPCWSTR
CString S3 ('' ', 100); // pre-allocate a 100-byte buffer, Fill with Spaces
CString S4 = "New Window Text";
// You CAN Pass a cstring in place of an lpctstr:
SetwindowText (HWNDSOMEWINDOW, S4);
// OR, Equivalently, Explicitly Cast The CString:
SetWindowText (HWNDSOMEWINDOW, (LPCTSTST) S4); you can load a string from your string table, a constructor of CString and the loadString () function can complete it. The format () method can read a string with a certain format from the string table. // Constructing / Loading from String Table
CSTRING S5 ((LPCTSTR) IDS_SOME_STR); // Load from String Table
CSTRING S6, S7;
// load from string table.
S6.LoadString (IDS_SOME_STR);
// load Printf-Style Format string from the string Table:
S7.FORMAT (IDS_SOME_FORMAT, "Bob", nsomestuff, ...); The first constructor looks a bit strange, but this is actually a method of loading a string description of the document. Note that a unique legal conversion character you can use is LPCTSTR for a CString variable. Convert to LPTSTR (Very quantity pointer) is wrong. The habit of converting a cString variable into lptstr will bring you harm, because when your program then crashes, you may not know why, because you have the same code everywhere, then they all work properly. . The correct way to get a very amount of pointer to the buffer is to call the getBuffer () method. Below is an example of the correct usage, this code is to set text to an item in a list control: cstring str = _t ("new text");
LVITEM ITEM = {0};
Item.mask = lvif_text;
Item.iitem = 1;
Item.psztext = (lpctstr) Str; // wrong! item.psztext = str.getBuffer (0); // Correct
ListView_SetItem (& item);
Str.ReleaseBuffer (); // Return Control of the Buffer To Str Psztext member is a LPTSTR variable, a very amount of pointer, so you need to call GetBuffer (). GetBuffer () parameters are the minimum length you need to cstring as a buffer allocation. If you need a modified buffer for some reason, you need to call GetBuffer (1024). When 0 is used as a parameter, getBuffer () returns a pointer to the current content of the string. The above scribe is compiled, and in this case, it can even work normally. But this does not mean that this line code is correct. By using a very varied conversion, you have destroyed object-oriented packages and make some assumptions for CSTRING's internal implementation. If you have such a transition habit, you will eventually fall into the level of code collapse. Why do you want the code to work properly, because you have the same code everywhere and those code look correct. Do you know how much people always complain about the current software? The bug in the software is because the programmer wrote incorrect code. Do you really want to write some code that you know is the wrong code? Is it a contribution to all the software? Take some time to learn using the correct way to use the CString to make your code work properly at any time. CString has two functions to create a BSTR from a CString. They are allocsystring () and setsystring (). // converting to bstr
CString S5 = "Bob!";
BSTR BS1 = NULL, BS2 = NULL;
BS1 = S5.Allocsystring ();
S5.Setsystring (& BS2);
Sysfreestring (BS1);
SysfreeString (BS2); Colevariant Colevariant and CComvariant. Very similar. Colevariant inherits from Variant, so it can pass to the function of receiving Variant. However, unlike CComvariant, Colevariant has only one LPCTSTR constructor. There is no constructor for LPCSTR and LPCWSTR. In most cases, this is not a problem, because no matter what your string is likely to be lpctsts, but this is a problem that needs to be realized. Colevariant has a constructor that receives a CString parameter. // conncture
CSTRING S1 = _T ("tchar string");
Colevariant v1 = _t ("bob"); // construct from an LPCTSTR
Colevariant V2 = S1; // Copy From A CSTRING, like CCOMVARIANT, you must directly access the member of Variant. If you need to convert Variant into a string, you should use the ChangeType () method. However, ColeVariant :: ChangeType () If the failure will throw an exception, not a HRESULT code that is a failed. // extracting data
Colevariant V3 = ...; // Fill In v3 from Somewhere
BSTR BS = NULL;
Try
{
v3.change type (vt_bstr);
BS = v3.bstrval;
}
Catch (ColeException * e)
{
// error, couldn''t convert
}
Sysfreestring (BS);
WTL CSTRING WTL's CString behavior is exactly the same as MFC's CString, so you can refer to the introduction of CString on MFC.
CLR and VC 7 system :: string are the .NET class used to handle strings. Internally, a String object contains an inverted string sequence. Any operation of the String object is actually returns a new String object because the original object is not changeable. One feature of String is if you have more than one String object contains the same character sequence, which actually points to the same object. Relative to C use extensions add a new string constant prefix S, S is used to represent a controlled string constant (a managed string literal). // conncture
String * ms = s "this is a nice managed string"; you can pass a non-controlled string to create a String object, but the sample is less losses that create the efficiency of the String object than using a controlled string. This is because all of the same string instances as a prefix represent the same object, but this is not applicable to non-controlled objects. The following code clearly clarifies this: string * ms1 = s "this is nice";
String * ms2 = s "this is nice";
String * ms3 = l "this is nice";
Console :: WriteLine (MS1 == MS2); // Prints True
Console :: WriteLine (MS1 == MS3); // Prints False The correct comparison may not use the S prefix string to use String :: Compareto () Console :: WriteLine (MS1-> Compareto (MS2));
Console :: WriteLine (MS1-> Compareto (MS3)); the above two lines of code are printed at 0, 0 indicates that two strings are equal. The conversion between String and MFC 7 cstring is easy. CString has a conversion operation to LPCTSTR, and String has two constructor that receives char * and wchar_t *, so you can pass a CString variable to a string constructor. CSTRING S1 ("Hello World");
String * S2 (S1); // Copy from a cstring reverse direction conversion is also similar to String * S1 = s "Three Cats";
CSTRING S2 (S1); this may make you feel confused, but it is indeed a role. Because from the VS.NET, CString has a constructor that receives the String object. CStringt (System :: string * pstring); For some quick operation, you may want to access the underlying string: string * s1 = s "three cats";
Console :: WriteLine (S1);
const __wchar_t __pin * pstr = ptrtostringChars (S1); for (int i = 0; I (* const_cast <__ wchar_t *> (pstr i)) ; Console :: WriteLine (S1); PTRTStringChars () Returns a const __wchar_t * of the underlying string, we need to fix it, otherwise the garbage collector may move it when we are managing its content. Using a string class in the Printf-style format function You must be very careful when you use a string package class in a printf () or similar function. These functions include sprintf () and its variants, as well as Trace and Atltrace Macros. Because these functions do not check the type of the added parameters, you must be careful, you can only pass them to the C language style string pointer, not a complete string class. For example, to pass a _bstr_t string to ATLTRACE (), you must use explicit conversion (LPCSTR) or (LPCWSTR): _ bstr_t bs = l "bob!"; ATLTRACE ("THE STRING IS:% S in line% D / N", (LPCSTR) BS, NLINE); if you forget to use a converter to pass the entire _bstr_t object to the function, it will show some meaningless Output, because the internal data saved in _BSTR_T will be all output. All class summary of the two string classes is common way: first convert the source string into a C language style string pointer and then pass this pointer to the constructor of the destination type. The following table shows how to convert a string into a C language style string pointer and which classes have a constructor that receives a C language style string pointer. Class String Type CONVERT to CHAR *? Convert to const char *? Convert to wchar_t *? Convert to const wchar_t *? Convert to BSTR? Construct from char *? Construct from wchar_t *? _ bstr_tbstryes cast1yes Cast YES CAST 1 Yes Castyes2 YES YES_VARIANT_TBSTRNONOCAST TO_BSTR_T3 Cast TO_BSTR_T3 YES YESSTRINGMBCS NOYES C_STR () Method Nonono YESNOWSTRINGUNICODE NO NO NO Yes c_str () Methodnono YESCCOMBSTRBSTR NO NO NOYES CAST to BSTRYES CAST YES YESCCOMVARIANT BSTR NO NO Noyes4 YES 4 YES YESCSTRING TCHAR NO6IN MBCSBUILDS, CAST NO 6in Unicodebuilds, Castno5 YES YESCOLEVARIANT BSTR NO NO NO YES 4 YES 4 In mbcsbuilds In UnicodeBuilds 1. Even if _bstr_t provides a conversion operator to a very amount of pointer, modify the bottom layer of buffer will also cause GPF if you overflow the buffer or cause memory leakage. 2 _BSTR_T Save BSTR internally with a WCHAR_T *, so you can use const wchar_t * to access BSTR. This is a detail, you can use it, this detail will change in the future. 3 If data cannot be converted to BSTR will throw an exception. 4 Using ChangeType (), then access to Variant's BSTRVAL member. In the MFC, it will throw an exception if the data conversion will be thrown. 5 There is no converting BSTR function here, but allocsysString () returns a new BSTR. 6 Using the getBuffer () method, you can temporarily get a very quite TCHAR pointer. About the author Michael Dunn: Michael Dunn lives in Sunshine City Los Angeles. He likes the weather here to live here for a lifetime. He started programming at the 4th grade, and the computer used was Apple // E. In 1995, a bachelor's degree in mathematics was obtained in UCLA, followed by QA engineers in Symantec, working in Norton AntiVirus. He learned from Windows and MFC programming. In 1999-2000, he designed and implemented a new interface of Norton Antivirus. Michael is now developing work in Napster (a company providing online subscription music service). He also developed UltraBar, an IE toolbar plugin, which allows web search to be easier, giving GoogleBar to combat it; he also developed CodeProject SearchBar; founded Zabersoft, which has an office in Los Angeles and Danish Odense. He likes to play games. The game has Pinball, Bike Riding, occasionally playing PS, DreamCasth, and MAME games. He was sad since I forgot my language: French, Chinese, and Japanese. Nishant S (Nish): Nish is from Microsoft Visual C MVP from Indian Trivandrum. He began coding since 1990. Now, Nish is working as a contract employee at home for CodeProject. He also wrote a romantic drama " Summer love and some more cricket "And a programming book" Extending MFC Applications with the .NET FRAMEWORK ". He also manager MVP a website http://www.voidnish.com/. On this website, you can see a lot of ideas and articles on programming. Nish is also planned In Tourism, he hopes that you can reach as much place on the earth.