Various data types BSTR, lpstr, lpwstr, cstring, variant, colevariant, _ variant_t, and ccombstr encountered in VC ++

Source: Internet
Author: User

BSTR, lpstr, lpwstr, cstring, variant, colevariant, _ variant_t, ccombstr, _ bstr_t visual c ++. net involves multiple programming methods such as ATL/ATL server, MFC, and hosting C ++. It is not only powerful but also widely used. In programming, we often encounter Character String Conversion operations for different encoding classes of ANSI, Unicode, and BSTR. This article first introduces the basic string type, then describes the related classes, such as ccombstr, _ bstr_t, and cstringt, and finally discusses their conversion methods, including using the latest atl7.0 conversion classes and macros, such as ca2ct and ca2tex.

I. BSTR, lpstr, and lpwstr

In all programming methods of Visual C ++. net, we often use such basic string types, such as BSTR, lpstr, and lpwstr. The reason for these data types is differentProgramming LanguageData exchange and support for ANSI, Unicode, and multi-byte character sets (MBCS.

So What Are BSTR, lpstr, and lpwstr?

BSTR (Basic string, basic string) is a unicode string of the olechar * type. It is described as a Type compatible with automation. Because the operating system provides corresponding API functions (such as sysallocstring) to manage it and some default SchedulingCodeTherefore, BSTR is actually a com string, but it is widely used in a variety of scenarios other than automation technology. Figure 1 describes the structure of BSTR, where the DWORD value is the actual number of bytes occupied by the string, and its value is twice the Unicode Character in the string.

Lpstr and lpwstr are a string data type used by Win32 and VC ++. Lpstr is defined as an eight-character ANSI character array pointer pointing to the end of null ('\ 0, lpwstr is a 16-bit dubyte character array pointer pointing to a null end. In VC ++, there are similar string types, such as lptstr and lpctstr. Their meanings are 2.

For example, "Long pointer to a constant generic string" indicates "a long pointer type pointing to a general String constant ", maps to const char * of C/C ++, while lptstr maps to char *.

Generally, the following types are also defined:

# Ifdef Unicode
Typedef lpwstr lptstr;
Typedef maid;
# Else
Typedef lpstr lptstr;
Typedef maid;
# Endif

Ii. cstring, cstringa, and cstringw

In Visual C ++. net, cstringt is used as the common string class shared by ATL and MFC. It has three forms: cstring, cstringa, and cstringw. These character types are tchar, Char, and wchar_t. Tchar is equivalent to wchar (16-bit Unicode character) on the UNICODE platform, and is equal to char in ANSI. Wchar_t is generally defined as unsigned short. Because cstring is used in MFCProgramIt is often used.

3. Variant, colevariant, and _ variant_t

In Ole, ActiveX, and COM, the variant data type provides a very effective mechanism because it includes both the data itself and the data type, therefore, it can realize various automatic data transmission. Let's take a look at a simplified version defined by variant in The IDL. h file:

Struct tagvariant {
Vartype VT;
Union {
Short ival; // vt_i2.
Long lval; // vt_i4.
Float fltval; // vt_r4.
Double dblval; // vt_r8.
Date; // vt_date.
BSTR bstrval; // vt_bstr.
...
Short * pival; // vt_byref | vt_i2.
Long * plval; // vt_byref | vt_i4.
Float * pfltval; // vt_byref | vt_r4.
Double * pdblval; // vt_byref | vt_r8.
Date * pdate; // vt_byref | vt_date.
BSTR * pbstrval; // vt_byref | vt_bstr.
};
};

Obviously, the variant type is a C structure, which contains a type member VT, some reserved bytes, and a large union type. For example, if VT is vt_i2, we can read the value of variant from ival. Similarly, when assigning values to a variant variable, you must specify its type first. For example:

Variant Va;
: Variantinit (& VA); // Initialization
Int A = 2002;
Va. Vt = vt_i4; // specifies the long data type.
Va. lval = A; // value assignment

To facilitate variable processing of the variant type, windows also provides such useful functions:

Variantinit -- initialize the variable to vt_empty;

Variantclear -- remove and initialize variant;

Variantchangetype -- change the variant type;

Variantcopy -- releases the memory connected to the target variant and copies the source variant.

The colevariant class encapsulates the variant structure. Its constructor has very powerful functions. When constructing an object, it first calls variantinit for initialization, and then calls the corresponding constructor according to the standard type in the parameter, and use variantcopy to convert and assign values. When the variant object is out of the valid range, its destructor will be automatically called. Because the Destructor calls variantclear, therefore, the corresponding memory will be automatically cleared. In addition, colevariant's value assignment operator provides great convenience for us in the conversion from variant type. For example, the following code:

Colevariant V1 ("this is a test"); // directly construct
Colevariant v2 = "this is a test ";
// The result is of the vt_bstr type and the value is "this is a test"
Colevariant V3 (long) 2002 );
Colevariant V4 = (long) 2002;
// The result is of the vt_i4 type and the value is 2002.

_ Variant_t is a variant class used for com. Its functions are similar to those of colevariant. However, when using the Visual C ++. Net MFC application, you must add the following two sentences before the code file:

# Include "comutil. h"

# Pragma comment (Lib, "comsupp. Lib ")

4. ccombstr and _ bstr_t

Ccombstr is an ATL class encapsulated for the bstr data type. It is easy to operate. For example:

Ccombstr bstr1;
Bstr1 = "bye"; // direct value assignment
Olechar * STR = olestr ("ta"); // width of 5 Characters
Ccombstr bstr2 (wcslen (STR); // defines the length as 5
Wcscpy (bstr2.m _ STR, STR); // copy the wide string to BSTR
Ccombstr bstr3 (5, olestr ("Hello World "));
Ccombstr bstr4 (5, "Hello World ");
Ccombstr bstr5 (olestr ("hey there "));
Ccombstr bstr6 ("hey there ");
Ccombstr bstr7 (bstr6 );
// Copy during construction. The content is "Hey there"

_ Bstr_t is the encapsulation of BSTR by C ++. Its constructor and destructor call the sysallocstring and sysfreestring functions respectively. Other operations use the bstr api functions. Similar to _ variant_t, comutil. h and comsupp. Lib must be added for use.

5. BSTR, char *, and cstring Conversion

(1) convert char * To cstring

If char * is converted to cstring, you can use cstring: format in addition to direct value assignment. For example:

Char charray [] = "this is a test ";
Char * P = "this is a test ";

Or

Lpstr P = "this is a test ";

Or in the use of Unicode applications that have been defined

Tchar * P = _ T ("this is a test ");

Or

Lptstr P = _ T ("this is a test ");
Cstring thestring = charray;
Thestring. Format (_ T ("% s"), charray );
Thestring = P;

(2) convert cstring to char *

If the cstring type is converted to the char * (lpstr) type, the following three methods are often used:

Method 1: use forced conversion. For example:

Cstring thestring ("This is a test ");
Lptstr lpsz = (lptstr) (lpctstr) thestring;

Method 2: Use strcpy. For example:

Cstring thestring ("This is a test ");
Lptstr lpsz = new tchar [thestring. getlength () + 1];
_ Tcscpy (lpsz, thestring );

It should be noted that the second parameter of strcpy (or _ tcscpy of Unicode/MBCS) is const wchar_t * (UNICODE) or const char * (ANSI ), the system compiler will automatically convert it.

Method 3: Use cstring: getbuffer. For example:

Cstring S (_ T ("this is a test");
Lptstr P = S. getbuffer ();
// Add the code using P here
If (P! = NULL) * P = _ T ('\ 0 ′);
S. releasebuffer ();
// Release immediately after use, so that other cstring member functions can be used.

(3) convert BSTR to char *

Method 1: Use convertbstrtostring. For example:

# Include
# Pragma comment (Lib, "comsupp. Lib ")
Int _ tmain (INT argc, _ tchar * argv []) {
BSTR bstrtext =: sysallocstring (L "test ");
Char * lpsztext2 = _ com_util: convertbstrtostring (bstrtext );
Sysfreestring (bstrtext); // release after use
Delete [] lpsztext2;
Return 0;
}

Method 2: Use the _ bstr_t value assignment operator to overload. For example:

_ Bstr_t B = bstrtext;
Char * lpsztext2 = B;

(4) convert char * To BSTR

Method 1: Use API functions such as sysallocstring. For example:

BSTR bstrtext =: sysallocstring (L "test ");
BSTR bstrtext =: sysallocstringlen (L "test", 4 );
BSTR bstrtext =: sysallocstringbytelen ("test", 4 );

Method 2: Use colevariant or _ variant_t. For example:

// Colevariant strvar ("this is a test ");
_ Variant_t strvar ("this is a test ");
BSTR bstrtext = strvar. bstrval;

Method 3: Use _ bstr_t, which is the simplest method. For example:

BSTR bstrtext = _ bstr_t ("this is a test ");

Method 4: Use ccombstr. For example:

BSTR bstrtext = ccombstr ("this is a test ");

Or

Ccombstr BSTR ("this is a test ");
BSTR bstrtext = BSTR. m_str;

Method 5: Use convertstringtobstr. For example:

Char * lpsztext = "test ";
BSTR bstrtext = _ com_util: convertstringtobstr (lpsztext );

(5) convert cstring to BSTR

Generally, cstringt: allocsysstring is used. For example:

Cstring STR ("this is a test ");
BSTR bstrtext = Str. allocsysstring ();
...
Sysfreestring (bstrtext); // release after use

(6) convert BSTR to cstring

Generally, you can perform the following operations:

BSTR bstrtext =: sysallocstring (L "test ");
Cstringa STR;
Str. Empty ();
STR = bstrtext;

Or

Cstringa STR (bstrtext );

(7) Conversion between ANSI, Unicode, and wide characters

Method 1: Use multibytetowidechar to convert ANSI to Unicode, and use widechartomultibyte to convert Unicode to ANSI.

Method 2: Use "_ t" to convert ANSI to a "general" string and use "L" to convert ANSI to Unicode, in the hosted C ++ environment, you can use s to convert an ANSI string to a string * object. For example:

Tchar tstr [] = _ T ("this is a test ");
Wchar_t wszstr [] = L "this is a test ";
String * STR = s "this is a test ";

Method 3: Use the conversion macro and class of ATL 7.0. Based on the original 3.0, atl7.0 has improved and added many Character String Conversion macros and provided corresponding classes. It has three unified forms:

Among them, the first c Represents a "class", so that the ATL 3.0 macro is different, the second C represents a constant, 2 represents a "to", and ex represents a buffer of a certain size. Sourcetype and destinationtype Can Be A, T, W, and OLE. The meanings are ANSI, Unicode, General, and Ole strings. For example, ca2ct converts ansi to a String constant of the normal type. The following is some sample code:

Lptstr tstr = ca2tex <16> ("this is a test ");
Lpctstr tcstr = ca2ct ("this is a test ");
Wchar_t wszstr [] = L "this is a test ";
Char * chstr = cw2a (wszstr );

Vi. Conclusion

Almost all programs use strings, while visual c ++. NET is powerful and widely used, so the conversion between strings is more frequent. This article involves almost all current conversion methods. Of course, for the. NET Framework, you can also use convert and text classes to convert different data types and character encodings.

Relationship and difference between cstring, BSTR, and lpctstr

Cstring is a dynamic tchar array, and BSTR is a string in a proprietary format (it needs to be manipulated using the functions provided by the system. The lpctstr is just a constant tchar pointer.

Cstring is a completely independent class, dynamic tchar array, and encapsulates operators such as + and string operation methods.
Typedef olechar far * BSTR;
Typedef const char * lpctstr;

Representation of various strings in VC ++

First, char * is a pointer to an ANSI character array, where each character occupies 8 bits (valid data is to remove the other seven bits), which is consistent with the traditional C, c ++ compatibility.

LP indicates a long pointer ). Lpstr is a pointer to an ANSI character array ending with '\ 0'. It can be used interchangeably with char *, and lpstr is often used in Win32.
The 'C' added in the lpcstr indicates "constant" (constant), indicating that this data type instance cannot be changed by using its API function. In addition, it is equivalent to lpstr.
1. LP indicates a long pointer. In Win16, there is a difference between a long pointer (LP) and a short pointer (P). In Win32, there is no difference, both 32-bit. therefore, the LP and P here are equivalent.
2. c Indicates const
3. What is t? We know that tchar is wchar_t in Unicode mode and compiled into char in general.

In order to meet the international needs of the program code, the industry has introduced the Unicode Standard, which provides a simple and consistent expression of the string method, all characters in the byte is a 16-bit value, the number of characters can also meet the encoding requirements of almost all written language characters in the world. Unicode (type: wchar_t) is an encouraging practice during development.

This produces lpwstr and lpcwstr. Their meanings are similar to lpstr and lpcstr, except that the character data is a 16-bit wchar_t instead of a char.

In order to realize the common use of the two types of encoding, tchar is defined as follows:
If _ Unicode is defined, the Declaration is as follows:
Typedef wchar_t tchar;
If _ Unicode is not defined, the Declaration is as follows:
Typedef char tchar;

The meaning in lptstr and lpctstr is that each character is such a tchar.

The characters in the cstring class are declared as tchar type. It provides an encapsulated class for your convenience.

Lpctstr:
# Ifdef _ Unicode
Typedef const wchar_t * lpctstr;
# Else
Typedef const char * lpctstr;
# Endif

Conversion of common VC Data Types

First, some common types of variables are defined to illustrate
Int I = 100;
Long L = 2001;
Float F = 300.2;
Double D = 12345.119;
Char username [] = "Woman Cheng peijun ";
Char temp [200];
Char * Buf;
Cstring STR;
_ Variant_t V1;
_ Bstr_t V2;

1. convert other data types to strings

Short INTEGER (INT)
ITOA (I, temp, 10); // convert I to a string and put it into temp. the last digit indicates decimal.
ITOA (I, temp, 2); // Binary Conversion
Long (long)
Ltoa (L, temp, 10 );
2. Obtain the pointer to the string from other variables containing the string

Cstring variable
STR = "2008 Beijing Olympics ";
Buf = (lpstr) (lpctstr) STR;
_ Variant_t variable of the BSTR type
V1 = (_ bstr_t) "programmer ";
Buf = _ com_util: convertbstrtostring (_ bstr_t) V1 );

Iii. Convert strings to other data types
Strcpy (temp, "123 ″);

Short INTEGER (INT)
I = atoi (temp );
Long (long)
L = atol (temp );
Floating Point (double)
D = atof (temp );

4. convert other data types to cstring

Use the cstring member function Format for conversion. For example:

INTEGER (INT)
Str. Format ("% d", I );
Float)
Str. Format ("% F", I );
Data Types supported by cstring constructors, such as string pointers (char *), can be directly assigned values.
STR = username;

V. BSTR, _ bstr_t and ccombstr

Ccombstr and _ bstr_t are encapsulation of BSTR, and BSTR is a 32-bit pointer to a string.
Char * can be converted to BSTR like this: bstr B = _ com_util: convertstringtobstr ("data"); // you need to add the header file comutil. h before use
Otherwise, use char * P = _ com_util: convertbstrtostring (B );
6. Variant, _ variant_t, and colevariant

For the Variant Structure, refer to the definition of the tagvariant struct in the header file vc98 \ include \ oaidl. h.
Assign a value to the variant variable: assign a value to the VT member to specify the data type, and then assign a value to the variable of the same data type in the union structure. For example:
Variant Va;
Int A = 2001;
Va. Vt = vt_i4; // specify Integer Data
Va. lval = A; // value assignment

For variant that is not immediately assigned a value, it is best to initialize with void variantinit (variantarg far * pvarg); in essence, the VT is set to vt_empty, the following table lists the correspondence between VT and common data:

unsigned char bval; vt_ui1
short ival; vt_i2
long lval; vt_i4
float fltval; vt_r4
double dblval; vt_r8
variant_bool boolval; vt_bool
scode; vt_error
Cy cyval; vt_cy
date; vt_date
BSTR bstrval; vt_bstr
iunknown far * punkval; interval
idispatch far * pdispval; vt_dispatch
safearray far * parray; vt_array | *
unsigned char far * pbval; vt_byref | vt_ui1
short far * pival; vt_byref | vt_i2
long far * plval; vt_byref | vt_i4
float far * pfltval; vt_byref | vt_r4
double far * pdblval; vt_byref | vt_r8
variant_bool far * pboolval; vt_byref | vt_bool
scode far * pscode; vt_byref | vt_error
Cy far * pcyval; vt_byref | vt_cy
date far * pdate; vt_byref | vt_date
BSTR far * pbstrval; vt_byref | interval
iunknown far * ppunkval; vt_byref | interval
idispatch far * handle; vt_byref | vt_dispatch
safearray far * pparray; vt_array | *
variant far * pvarval; vt_byref | vt_variant
void far * byref; vt_byref

_ Variant_t is the encapsulation class of variant, and its value assignment can be forced type conversion. Its constructor will automatically process these data types.
For example:
Long L = 222;
Ing I = 100;
_ Variant_t lval (L );
Lval = (long) I;

The use of colevariant is basically the same as that of the _ variant_t method. See the following example:
Colevariant V3 = "string", V4 = (long) 1999;
Cstring STR = (BSTR) v3.pbstrval;
Long I = v4.lval;

VII. Others

During message processing, we often need to split wparam, lparam, and other 32-bit data (DWORD) into two 16-bit data (Word), for example:
Lparam;
Word lovalue = loword (lparam); // take 16 bits
Word hivalue = hiword (lparam); // The height is 16 bits.
For a 16-bit data (Word), we can use the same method to break down the high and low 8-bit data (byte), for example:
Word wvalue;
Byte lovalue = lobyte (wvalue); // get 8 bits
Byte hivalue = hibyte (wvalue); // The value is 8 bits in height.

How to assign a variable of the cstring type to a variable of the char * type
1. getbuffer function:
Use the cstring: getbuffer function.
Char * P;
Cstring STR = "hello ";
P = Str. getbuffer (Str. getlength ());
Str. releasebuffer ();

When converting cstring to char *
Cstring STR ("aaaaaaa ");
Strcpy (Str. getbuffer (10), "AA ");
Str. releasebuffer ();
Call getbuffer (int n) when we need a character array, where N is the length of the character array we need. Call releasebuffer () immediately after use ();
It is also important that you do not use char * Where const char * can be used *

2. memcpy:
Cstring MCS = _ T ("CXL ");
Char MCH [20];
Memcpy (MCH, MCS, 20 );

3. Use lpctstr for forced conversion: Do not use it whenever possible
Char * Ch;
Cstring STR;
Ch = (lpstr) (lpctstr) STR;

Cstring STR = "good ";
Char * TMP;
Sprintf (TMP, "% s", (lptstr) (lpctstr) Str );

4,
Cstring MSG;
MSG = MSG + "ABC ";
Lptstr lpsz;
Lpsz = new tchar [msg. getlength () + 1];
_ Tcscpy (lpsz, MSG );
Char * psz;
Strcpy (psz, lpsz );
Cstring class to const char * Conversion
Char A [100];
Cstring STR ("aaaaaa ");
Strncpy (A, (lpctstr) STR, sizeof ());
Or:
Strncpy (A, STR, sizeof ());
The preceding two methods are correct. Because the second parameter type of strncpy is const char *, the compiler automatically converts the cstring class to const char *.

Cstring to lpctstr (const char *)
Cstring CSTR;
Const char * maid = (lpctstr) CSTR;

Convert the string type to the string type
Maid;
Cstring CSTR = lpctstr;

Assign a char * type variable to a cstring type variable.
Values can be assigned directly, for example:
Cstring mystring = "this is a test ";
You can also use constructors, such:
Cstring S1 ("Tom ");

Assign a variable of the cstring type to a variable of the char [] type (string ).
1. sprintf () function
Cstring STR = "good ";
Char TMP [200];
Sprintf (TMP, "% s", (lpcstr) Str );
This forced conversion is equivalent to (lptstr) (lpctstr) Str
When the cstring class variables need to be converted to (char *), use (lptstr) (lpctstr) Str

However, the lpctstr is const char *, that is, the resulting string cannot be written! It is extremely dangerous to forcibly convert it to lptstr to remove const!
If you don't care, you will be finished! To obtain char *, use getbuffer () or getbuffersetlength (). Call releasebuffer () after use ().

2. strcpy () function
Cstring STR;
Char C [256];
Strcpy (C, STR );

Char mychar [1024];
Cstring source = "Hello ";
Strcpy (char *) & mychar, (lpctstr) source );
Use of cstring
1. Specify cstring Parameters
For most functions that require string parameters, it is best to specify the form parameter in the function prototype as a const pointer pointing to the character (lpctstr) rather than the cstring.
When you specify a parameter as a const pointer to a character, you can pass the pointer to a tchar array (such as a string ["Hi There"]) or to a cstring object.
The cstring object is automatically converted to the lpctstr. Cstring objects can also be used wherever the lpctstr can be used.

2. If a parameter is not modified, the parameter is also specified as a constant string reference (const cstring &). If the function needs to modify the string,
Delete the const modifier. If the default value is null, initialize it as a Null String [""], as shown below:
Void addcustomer (const cstring & name, const cstring & Address, const cstring & comment = "");

3. For most function results, return the cstring object by value.
Basic string operations
Many advanced Languages provide operators or standard library functions for basic string operations.
To facilitate the description, first define several related variables:
Char S1 [20] = "dir/bin/appl", S2 [20] = "file. ASM", S3 [30], * P;
Int result;
The following describes the basic operations of strings in C language.
1. Obtain the string length
Int strlen (char * s); // evaluate the length of string s
[Example] printf ("% d", strlen (S1); // output the string length of S1 12

2. String Replication
Char * strcpy (char * To, * From); // copy the from string to string and return the pointer to start
[Example] strcpy (S3, S1); // S3 = "dir/bin/appl", S1 string unchanged
3. Join
Char * strcat (char * To, char * From); // copy the from string to the end of the string,
// Returns the pointer at the beginning of the to string.
[Example] strcat (S3, "/"); // S3 = "dir/bin/appl /"
Strcat (S3, S2); // S3 = "DIR/bin/appl/file. ASM"

4. String comparison
Int strcmp (char * S1, char * S2); // compare the sizes of S1 and S2,
// When S1 <S2, S1> S2 and S1 = S2, return values smaller than 0, greater than 0, and equal to 0, respectively.
[Example] result = strcmp ("Baker", "Baker"); // result> 0
Result = strcmp ("12", "12"); // result = 0
Result = strcmp ("Joe", "Joseph") // result <0

5. Character locating
Char * strchr (char * s, char C); // locate the first occurrence of C in string S,
// If it is found, the location is returned; otherwise, null is returned.
[Example] P = strchr (S2, '.'); // P points to the location after "file"
If (p) strcpy (P, ". cpp"); // S2 = "file. cpp"

Note:
① The above operations are the most basic, among which the last four operations are also variant forms: strncpy, strncath and strnchr.
② For other string operations, see <string. h> of C. In different advanced languages, the types and symbols of string operations are different.
③ Other string operations can generally be combined by these basic operations

[Example] The Sub-string operation can be implemented as follows:
Void substr (char * sub, char * s, int POs, int Len ){
// S and sub are character arrays. sub is used to return the substring whose length is Len starting from the second POS character of string S.
// 0 <= POS <= strlen (S)-1, and the array sub can contain at least Len + 1 characters.
If (Pos <0 | POS> strlen (S)-1 | Len <0)
Error ("parameter error !");
Strncpy (sub, & S [POS], Len); // copy up to Len characters from S [POS] to sub

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.