Been studying what I thought was a fairly authoritative article about BSTRs by Bruce McKinney...
where he states that the four bytes before the start of the BSTR contains the string's length. Here is the exact quote...
What Is a BSTR? The BSTR type is actually a typedef, which in typical Windows include file fashion, is made up
of more typedefs and defines. You can follow the twisted path yourself, but here's what it boils down to:typedef wchar_t * BSTR;
Hmmm. A BSTR is actually a pointer to Unicode characters. Does that look familiar? In case you don't recognize
this, let me point out a couple of similar typedefs:typedef wchar_t * LPWSTR;
typedef char * LPSTR;So if a BSTR is just a pointer to characters, how is it different from the null-terminated strings that C++
programmers know so well? Internally, the difference is that there's something extra at the start and end of the
string. The string length is maintained in a long variable just before the start address being pointed to, and the
string always has an extra null character after the last character of the string. This null isn't part of the
string, and you may have additional nulls embedded in the string.
However, my tests prove this to be most untrue. Here is a program with the output directly afterwards where I'm using a simple string as follows for testing purposes...
OLECHAR szOleChar[]=L"Here Is Some Text";
That string contains 17 characters. An Ansi string would need a memory allocation of 18 characters to hold it, and I expect a wide character string something like 36 characters. I'd expect the system string functions in oleauto.dll that create and manage BSTRs would need a few more if they are going to preface these things with some kind of length information whether it be counts of characters or actual memory allocation counts of bytes. Having said that, can someone explain to me the results of the below program where I'm coming up with 34 bytes stored in the four byte slot right before the start of the BSTR???
#include <windows.h>
#include <stdio.h>
int main(void)
{
OLECHAR szOleChar[]=L"Here Is Some Text";
unsigned int iLen=0;
int* pBStrLen=0;
wchar_t* pChar;
BSTR strText;
iLen=wcslen(szOleChar);
printf("iLen = %u\n",iLen);
strText=SysAllocStringLen(szOleChar,iLen);
printf("SysStringLen(strText) = %u\n", SysStringLen(strText));
wprintf(L"strText = %s\n", strText);
printf("strText = %u\n", (unsigned)strText);
pBStrLen=(int*)strText;
pBStrLen--;
printf("pBStrLen = %u\n", (unsigned)pBStrLen);
printf("*pBStrLen = %u\n\n",(unsigned int)*pBStrLen);
pChar=strText;
for(unsigned int i=0; i<iLen; i++)
{
wprintf(L"%u\t%u\t\t%c\n", i, pChar, *pChar);
pChar++;
}
SysFreeString(strText);
getchar();
return 0;
}
/*
iLen = 17
SysStringLen(strText) = 17
strText = Here Is Some Text
strText = 2312572
pBStrLen = 2312568
*pBStrLen = 34
0 2312572 H
1 2312574 e
2 2312576 r
3 2312578 e
4 2312580
5 2312582 I
6 2312584 s
7 2312586
8 2312588 S
9 2312590 o
10 2312592 m
11 2312594 e
12 2312596
13 2312598 T
14 2312600 e
15 2312602 x
16 2312604 t
*/