Click to See Complete Forum and Search --> : ansi version of bstr


Lewis_Miller
February 23rd, 2005, 10:35 AM
Hi all,
Im trying to create a string that is an ansi like (single char) version of a bstr. if i understand it correctly a bstr is conceptually laid out in memory with tchar's and the first 2 tchar's are the length, as in:

in bytes: length \0\0\0\0 | data (tchar's) |null \0\0
or in tchars: length str[0] str[1] | data str[2]...str[n] | null str[last]
and the bstr variable actually points to str[2] .

what im attempting to do is create a similar version that uses single bytes (as opposed to tchar's)... something like this:
length (unsigned long) \0\0\0\0 | null terminated c string

the problem im having is finding syntax to set/get the length in the first four bytes with the length of the remaining data (minus the null) i tried to use the kernel function MoveMemory to copy the length into the first four bytes but it seems to wipe out the rest of the string. Ive tried somethign like this:

typedef ubyte unsigned char

ubyte *loadstr(const char *s,int length) {
ubyte * snew = (ubyte *)malloc(length +5);
if (s) {
//how to set length here?
//RtlMoveMemory(&s,&snew,4);

int i = 5;
while (s) {
*snew[i] = (ubyte)*s++;
i++;
}
}

return &snew[5];
}

any help or pointers in the right direction would be much appreciated.
Regards
Lewis

Yves M
February 23rd, 2005, 12:48 PM
The first thing to ask is probably obvious: Why do you want to do this anyways? What is wrong with using something like std::string (where the length is stored separately anyways)?

Now, the main problem you will be having is the distinction between char* and your strings. Let's call your type of strings astr for the sake of the rest of my post.

Now, if you want your astr to behave like a bstr then all operations on it have to go through your own functions and you won't be able to use strcpy, strcat etc. I guess that is clear already. Now, one thing that does not seem to be clear is that a BSTR pointer actually points to the beginning of the string, not the 4 bytes of length information. So if you were to write your own version of strcpy, it could look like this:

typedef char *astr;

astr acpy(const astr orig)
{
// The length information is supposedly correct and there, so use it to get the total length
unsigned int *pLen = reinterpret_cast<unsigned int *> (orig - 4);
// Now allocate the new memory
astr retVal = (char *) malloc(*pLen + 5);
// copy the memory
memcpy(retVal, orig - 4, *pLen + 5);
// return a pointer to the string's start
return retVal + 4;
}

Because of this, you will have to have your own functions for allocating, deallocating, copying, appending etc.

It can be done, but it seems a bit pointless to me. As I said in the beginning, using std::string would be an easier (and probably faster) option. If it's just as an exercise, it's OK though.

Lewis_Miller
February 24th, 2005, 08:26 AM
ty for the help yves m,
Your code will be the extra help i need to accomplish this. The reason i am doing this is because im writing a basic to c++ converter, and i want to avoid using c++ libraries if at all possible. I am still new on some concepts in c++ but im learning fast :)

thanks again
Lewis