Solved

BSTR strngs kill me

Posted on 2006-06-21
15
431 Views
Last Modified: 2012-06-27
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
Comment
Question by:GiedriusS
  • 6
  • 4
  • 2
  • +2
15 Comments
 
LVL 11

Assisted Solution

by:Jase-Coder
Jase-Coder earned 25 total points
ID: 16949646
change csVal = bstrVal; to csVal = CString(bstrVal);
0
 
LVL 11

Expert Comment

by:Jase-Coder
ID: 16949653
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
 
LVL 48

Assisted Solution

by:AlexFM
AlexFM earned 25 total points
ID: 16949687
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
 
LVL 39

Accepted Solution

by:
itsmeandnobodyelse earned 25 total points
ID: 16950379
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
 

Author Comment

by:GiedriusS
ID: 16950490
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
 

Author Comment

by:GiedriusS
ID: 16950533
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
 
LVL 39

Expert Comment

by:itsmeandnobodyelse
ID: 16950635
>>>> 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
Highfive + Dolby Voice = No More Audio Complaints!

Poor audio quality is one of the top reasons people don’t use video conferencing. Get the crispest, clearest audio powered by Dolby Voice in every meeting. Highfive and Dolby Voice deliver the best video conferencing and audio experience for every meeting and every room.

 
LVL 39

Expert Comment

by:itsmeandnobodyelse
ID: 16950654
>>>> 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
 

Author Comment

by:GiedriusS
ID: 16951087
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
 

Author Comment

by:GiedriusS
ID: 16951489
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
 

Author Comment

by:GiedriusS
ID: 16951639
problem solved.. thaks for your help:)
0
 
LVL 3

Assisted Solution

by:Dimkov
Dimkov earned 25 total points
ID: 16951641
Can you try to deallocate the memory after calling Function2 ?
0
 
LVL 3

Expert Comment

by:Dimkov
ID: 16951645
what was the solution?
0
 

Author Comment

by:GiedriusS
ID: 16951710
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
 
LVL 39

Expert Comment

by:itsmeandnobodyelse
ID: 16951785
>>>> 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

IT, Stop Being Called Into Every Meeting

Highfive is so simple that setting up every meeting room takes just minutes and every employee will be able to start or join a call from any room with ease. Never be called into a meeting just to get it started again. This is how video conferencing should work!

Join & Write a Comment

Often, when implementing a feature, you won't know how certain events should be handled at the point where they occur and you'd rather defer to the user of your function or class. For example, a XML parser will extract a tag from the source code, wh…
Container Orchestration platforms empower organizations to scale their apps at an exceptional rate. This is the reason numerous innovation-driven companies are moving apps to an appropriated datacenter wide platform that empowers them to scale at a …
The viewer will learn how to pass data into a function in C++. This is one step further in using functions. Instead of only printing text onto the console, the function will be able to perform calculations with argumentents given by the user.
The viewer will learn additional member functions of the vector class. Specifically, the capacity and swap member functions will be introduced.

706 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

18 Experts available now in Live!

Get 1:1 Help Now