A Discussion about the conversion between BSTR, BSTR, and char.

Source: Internet
Author: User

Question:
Bstr a = _ bstr_t ("");
Bstr B = _ bstr_t ("B ");
Cstring C;
C =;
MessageBox (C );
C = B;
MessageBox (C );
Why is B displayed in the message box?

If so:
_ Bstr_t bstr1 ("");
Bstr a = bstr1;
_ Bstr_t bstr2 ("B ");
Bstr B = bstr2;
Cstring C;
C =;
MessageBox (C );
C = B;
MessageBox (C );
The message box is displayed!

There are still questions:
In VB, The BSTR defined in midl is 4 bytes length + String
Olechar * is defined in VC *

Why are the definitions of BSTR inconsistent?

// Reply to 1 response -----------------------------------------------------------------------------------------------------------------
//ProgramThis should be the case
 
_ Bstr_t A = _ bstr_t ("");
_ Bstr_t B = _ bstr_t ("B ");
Cstring C;
C = A. Copy ();
MessageBox (C );
C = B. Copy ();
MessageBox (C );

Note:
_ Bstr_t is a class used to manipulate the BSTR data type,

Bstr a = _ bstr_t ("");
_ Bstr_t ("A"); The type returned by the constructor is void,

Therefore, the above sentence means that a random address is returned to;
C = A; after execution;
C points to a random area in the memory, and the display is random;
----------------
Cstring is also a class,
Use the member function. Copy of the _ bstr_t class to return a BSTR backup!

// Reply 2 again -----------------------------------------------------------------------------------------------------------------
// Question 1:

First, we must make it clear that _ bstr_t is the encapsulation of BSTR.

Code 1:
Bstr a = _ bstr_t ("");
// Here, _ bstr_t ("A") is only a temporary object. When it is initialized (including an internal BSTR) and assigned to bstr a, it is revoked. The value assigned by it is the address of BSTR.
Bstr B = _ bstr_t ("B ");
// The second time, a temporary object is still generated, and the initialization process is the same as above. In addition, because the previous _ bstr_t object has been revoked, the address for generating BSTR is also the same as that for generating BSTR.
// Therefore, in fact, a and B point to the same address. The content of this address is written twice.

Code 2:
_ Bstr_t bstr1 ("");
Bstr a = bstr1;
_ Bstr_t bstr2 ("B ");
Bstr B = bstr2;
// Here two _ bstr_t bstr1 and bstr2 are both local objects and exist at the same time. Therefore, the BSTR addresses they contain are different. In this way, assigning values separately is okay.

> Bstr a = _ bstr_t ("");
>>_Bstr_t ("A"); The type returned by the constructor is void,
> So the above sentence means that a random address is returned to;
> C = A; after execution;
> C points to a random area in the memory, and the display is random;

In fact, the value assignment statement, that is, the "=" operator, does not return the return value of the constructor of this object!
It is determined by the = Operator and type conversion operator of the object.
For _ bstr_t, it has:

_ Bstr_t: wchar_t *, _ bstr_t: char *
Operator const wchar_t * () const throw ();
Operator wchar_t * () const throw ();

Operator const char * () const throw (_ com_error );
Operator char * () const throw (_ com_error );

Therefore, c = A does not return a random address, but the BSTR address contained in it.

// Reply to 3 response -----------------------------------------------------------------------------------------------------------------

Defining in VC,

# If defined (win32 )&&! Defined (ole2ansi)
Typedef wchar olechar;
# Else
Typedef char olechar;
# Endif
Typedef olechar * BSTR;

In fact, BSTR directly points to the first address of the string (double byte or ANSI string ).
The four bytes before BSTR are the length of the string, which is generated by the compiler.CodeThe length is automatically read, rather than "\ 0" to identify the end of the string.
The definitions in different languages seem different, but the actual storage and access methods are the same. This is not surprising.

// Reply to 4 rows -----------------------------------------------------------------------------------------------------------------
The BSTR string has the following key points to emphasize:
1. a bstr string variable is actually a pointer variable. It occupies 32 bits (4 bytes), just like other pointers. It also points to a character array in unicode format. However, we cannot equate a string with a BSTR string. We must use its own exact name-"BSTR".
2. the string array to which a BSTR string variable points must start with four Reserved characters (the number of bytes of the string array is saved, rather than the number of characters) and end with two null characters.
3. Since null characters may appear anywhere in a unicode string, it is not appropriate to declare the end of a string in unicode format with null characters. Therefore, it is vital to save the length of a string among the four Reserved Words.
4. Let's emphasize that the BSTR string pointer actually points to the first address of the character array in unicode format, rather than the four bytes at the beginning. Next we will see that here we will not bother to emphasize that the characteristics of BSTR string variables are to compare with the string type in VC ++ that will be explained soon.
5. The length of the first four bytes records the number of bytes in the character array (note, not the number of characters), including the trailing NULL bytes. Because the array is in unicode format, the actual character is half of the length.
Here, we emphasize that an empty character in unicode format occupies 2 bytes rather than 1 byte. Consider this when testing null characters in an array in unicode format.
Generally, the BSTR string "help" is "a BSTR string ". It is generally assumed that a string variable pointing to a character array contains at least two null characters.
For Visual Basic, the two empty bytes before and after the BSTR string are useless, but they are crucial for Win32. The reason is that the Win32 Unicode string (lpwstr) is defined as a pointer to a unicode format string ending with an empty character.
It is reasonable to explain why the BSTR string should end with an empty character. The following describes the C ++ string variables.
Two sentences of code:
Dim STR as string
STR = "Help"
STR indicates the name of a BSTR string variable, rather than a character array in unicode format. In other words, STR is the name of a variable that saves the address XXXX.
The following is a small experiment. It indicates that the string variable in Visual Basic is a pointer to the character array rather than a character array. The following defines a structure. Its member variable type is string.
Private tyep uttest
Astring as string
Bstring as string
End type
Dim Utest as uttest
Dim s as string
S = "testing"
Utest. astring = "testing"
Utest. astring = "testing"
Debug. Print Len (s)
Debug. Print Len (Utest)
The code execution result is:
7
8
For the string variable, the Len function returns the number of characters in the string array. Therefore, the 7-character string "testing" returns 7. For the structure variable Utest, the Len function returns the memory space occupied by the structure. Therefore, the return value 8 clearly shows that each BSTR variable occupies 4 bytes in memory. Because BSTR is a Win32 pointer!
C-type lpstr and lpwstr strings
Visual c ++ uses lpstr and lpwstr strings.
The lpstr string is defined as a pointer to an ANSI String Array ending with a NULL byte. However, because we determine the termination of the lpstr string at the position of NULL bytes, the second Null Byte in the lpstr string is not allowed. Similarly, lpwstr is a pointer to a string in the unicode format terminated by a Null Byte. It does not allow the presence of Null Byte in the middle. W in lpwstr refers to wide, which is another Microsoft statement about Unicode.

We may also encounter a string of the lpcstr and lpcwstr types. C Indicates constant (constant ). This string cannot be modified by API functions. In addition, both the lpcstr and lpstr are the same. Similarly, apart from being unchangeable, the other methods are the same as those of lpwstr.
In addition, lptstr and lptstr are generally used in Conditional compilation, just like tchar. The following is an example code:
# Ifdef Unicode
Typedef lpwstr lptstr; // in UNICODE, lptstr and lpwstr are the same
Typedef lpcwstr lpctstr; // in UNICODE, The lpctstr and the lpcwstr are the same
# Else
Typedef lpstr lptstr; // in ANSI, The lptstr and lpstr are the same
Typedef lpcstr lpctstr; // in ANSI, lptcstr is the same as that in lpcstr.
# Endif
Only remember that C only means read-only.

// Reply to Step 5 -----------------------------------------------------------------------------------------------------------------

In fact, andrew_var (Andrew) is correct, because BSTR is just a pointer to olechar, and the Temporary Variable _ bstr_t is assigned to BSTR and destroyed, therefore, the memory block allocated to _ bstr_t ("A") during creation is released, and this memory is then allocated to _ bstr_t ("B "), the memory is also released after the assignment. Therefore, both BSTR (a and B) point to the same memory block. You can check the addresses of A and B to determine this, the memory block is released and can be allocated. You can modify the first code as follows:

Bstr a = _ bstr_t ("");
Bstr B = _ bstr_t ("B ");
_ Bstr_t bstr3 (_ T ("C "));
_ Bstr_t bstr4 (_ T ("D "));

Cstring C;
C =;
MessageBox (C );
C = B;

C = (lpctstr) bstr3;
MessageBox (C );
C = (lpctstr) bstr4;
MessageBox (C );

This can be explained, while the class is different. Although it is a temporary object, the memory allocated by it will be released only when it exceeds the scope (lifetime, therefore, "C" won't be overwritten by "D.
In VC, BSTR also has four bytes before the string pointer, specifying the length of the string

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.