• Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 492
  • Last Modified:

BSTR strngs kill me

Hi,

what is the difference between these two code examples:
BSTR bstrVal;
Function(&bstrVal);
CStrng csVal;
csVal = bstrVal;
Function2(csVal.AllocSysString());

and

CStrng csVal;
csVal = "blabla";
Function2(csVal.AllocSysString());

why?
the first code does not work Function2 gets NULL string and the second works properly Function2 gets "blabla"
0
GiedriusS
Asked:
GiedriusS
  • 6
  • 4
  • 2
  • +2
4 Solutions
 
Jase-CoderCommented:
change csVal = bstrVal; to csVal = CString(bstrVal);
0
 
Jase-CoderCommented:
In a BSTR the length of the string is stored at the start of the memory allocated for the string so when you do just an assignment your not really assigning the string to your CString varible
0
 
AlexFMCommented:
BSTR bstrVal;
Function(&bstrVal);

I guess this should not compile - you are trying to call BSTR function with BSTR* parameter. Anyway, BSTR must point to valid string, and bstrVal is unassigned pointer.

CStrng csVal;
csVal = bstrVal;

You try to use unassigned value bstrVal here. Why should it work?

BSTR bstrVal = SysAllocString(L("blabla"));
Function2(bstrVal);
SysFreeString(bstrVal);

This one can work.
0
Technology Partners: We Want Your Opinion!

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

 
itsmeandnobodyelseCommented:
The definition of BSTR is

    typedef OLECHAR *BSTR;

and OLECHAR is defined as WCHAR (wide character == UNICODE character).

Hence, BSTR is simply a pointer (and not a class type). So, your sequence

  BSTR bstrVal;
  Function(&bstrVal);

defines a pointer bstrval which has an undefined value as AlexFM already explained (some compilers may set the pointer to NULL in debug mode) and the next statement passes the address of the pointer variable bstrval to Function.

As AlexFM already told you, the above could not work.

If

   Function(&bstrval);   // requires void Function(BSTR*)

is a typo and should be

   Function2(bstrval);

you would need a proper initialisation. That can be done by using CString::AllocSysString (and *not* vice versa)

  CString str = "blabla";
  BSTR bstrval = str.AllocSysString();
  Function2(bstrval);

You may call

  ::SysFreeString(bstrval);

after use but make sure that no other thread or COM still is using the string.

Regards, Alex



 




0
 
GiedriusSAuthor Commented:
I tried to print the csVal to the file. Both ways gave the same result, but when I pass this to the function COM2 dll they are different:(

I have the feeling that this is because of strings, that are not the same representation in memory.

Yes this code works:
Function2(SysAllocString(L("blabla")));

but:
Function2(SysAllocString(csVal.GetString()));
does not

I don't get it.. it seems like Function(&bstrVal); ruins everything. Function is a function in other COM dll (it could be written in other programming language), when the result is from this function given to Function2 it won't work, when I enter the value by hand everything is OK.
How should I pass Function result to Function2?
0
 
GiedriusSAuthor Commented:
I guess that Function allocates memory for BSTR:
&bstrVal is type of BSTR *, so it can allocate memory for BSTR *, and return it (because I use &bstrVal, I pass this variable by value).

The result from Function is ALWAYS correct, I print it to the file.. but it could not be passed to Function 2.. could it be because of the use of Unicode character set in my project and the difference od character sets in other dll files?
0
 
itsmeandnobodyelseCommented:
>>>> but:
>>>> Function2(SysAllocString(csVal.GetString()));
>>>> does not

Didn't you read my comment? You need to use

    csVal.AllocSysString()

if you want to convert the contents of csVall to a (valid) BSTR.

If you add function names at random, your code will never compile.


>>>> I don't get it.. it seems like Function(&bstrVal); ruins everything

Could you post the declaration (prototype)  both of Function and Function2. What is the purpose of these functions? If you pass uninitialized pointers (or "blabla") to any of these functions, I wouldn't expect any valid output.

Regards, Alex

0
 
itsmeandnobodyelseCommented:
>>>> but it could not be passed to Function 2..

try

   BSTR* pbstrval = NULL;
   Function(pbstrval);   // pass pointer to pointer (and get valid pointer back);
   Function2(*pbstrval); // pass dereferenced pointer


Regards, Alex
0
 
GiedriusSAuthor Commented:
prototypes:

virtual HRESULT Function(BSTR * bstrVal);
(the real name is virtual HRESULT get_Name(BSTR * bstrVal);)

virtual HRESULT Function2(BSTR bstrVal);
(the real name is virtual HRESULT Add(BSTR bstrVal);)
0
 
GiedriusSAuthor Commented:
I found out that the problem was because of a cycle:
when i run this code cycle one time everything is OK..

for(..)
{
  BSTR bstrVal;
  Function(&bstrVal);
  Function2(bstrVal);
}

I tried dynamically allocating memory
for(..)
{
  BSTR * bstrVal;
  bstrVal = (BSTR*)malloc(sizeof(BSTR));
  Function(bstrVal);
  Function2(*bstrVal);
}

still no luck:( only works when cycle runs one time
0
 
GiedriusSAuthor Commented:
problem solved.. thaks for your help:)
0
 
DimkovCommented:
Can you try to deallocate the memory after calling Function2 ?
0
 
DimkovCommented:
what was the solution?
0
 
GiedriusSAuthor Commented:
the cycle failed on 2 step...
because Function returned empty string on second step..
the empty string gave a NULL value.. (I guess Function2 did not allow NULL's and failed all the chain modification) I don't know the realization of that function so I dont know how it does this, but that was very strange effect of NULL strings..

I don't know how to explain this.
Anyway thanks.
0
 
itsmeandnobodyelseCommented:
>>>> bstrVal = (BSTR*)malloc(sizeof(BSTR));

You may not do that cause obviously Function "get_Name" allocates memory for the BSTR. If you allocate memory prior to the call of Function it is a leak. Furthermore, sizeof(BSTR) only returns 4 what is the size of the pointer.

>>>> when i run this code cycle one time everything is OK

What happens in the second run? Does it crash? And what do you expect to happen?

Note, a function called 'get_Name' which allocates storage for a passed string pointer not necessarily expects to be called in a loop. Why should anyone try to get the same name twice? You simply could do that:

    BSTR bstrVal = NULL;   // always initialize plain pointer variables !!!!
    Function(&bstrval);      // get name only once
    for (...)
    {
          Function2(bstrVal);   // *bstrval is wrong if bstrval isn't a BSTR*
    }


Regards, Alex

0

Featured Post

Free Tool: Path Explorer

An intuitive utility to help find the CSS path to UI elements on a webpage. These paths are used frequently in a variety of front-end development and QA automation tasks.

One of a set of tools we're offering as a way of saying thank you for being a part of the community.

  • 6
  • 4
  • 2
  • +2
Tackle projects and never again get stuck behind a technical roadblock.
Join Now