To handle strings that are allocated by one component and freed by another, Automation defines a special set of functions. These functions use the following data type:
typedef OLECHAR FAR* BSTR;
These strings are zero-terminated, and in most cases they can be treated just like OLECHAR* strings. However, you can query a BSTR for its length rather than scan it, so it can contain embedded null characters. The length is stored as an integer at the memory location preceding the data in the string. Instead of reading this location directly, applications should use the string manipulation functions to access the length of a BSTR.
In situations where a BSTR will not be translated from ANSI to Unicode, or vice versa, you can use BSTRs to pass binary data. For example, if code will run only on 16-bit systems and interact only with other 16-bit systems, you can use BSTRs. The preferred method of passing binary data is to use a SAFEARRAY of VT_UI1.
In 32-bit OLE, BSTRs use Unicode like all other strings in 32-bit OLE. In 16-bit OLE, BSTRs use ANSI. Win32 provides MultiByteToWideChar and WideCharToMultiByte to convert ANSI strings to Unicode, and Unicode strings to ANSI. Automation caches the space allocated for BSTRs. This speeds up the SysAllocString/SysFreeString sequence. However, this may also cause IMallocSpy to assign leaks to the wrong memory user because it is not aware of the caching done by Automation.
For example, if the application allocates a BSTR and frees it, the free block of memory is put into the BSTR cache by Automation. If the application then allocates another BSTR, it can get the free block from the cache. If the second BSTR allocation is not freed, IMallocSpy will attribute the leak to the first allocation of the BSTR. You can determine the correct source of the leak (the second allocation) by disabling the BSTR caching using the debug version of Oleaut32.dll, and by setting the environment variable OANOCACHE=1 before running the application.
A null pointer is a valid value for a BSTR variable. By convention, it is always treated the same as a pointer to a BSTR that contains zero characters. Also by convention, calls to functions that take a BSTR reference parameter must pass either a null pointer, or a pointer to an allocated BSTR. If the implementation of a function that takes a BSTR reference parameter assigns a new BSTR to the parameter, it must free the previously referenced BSTR.