BSTR vs. _bstr_t

VC

    Sponsored Links

    Next

  • 1. VC 2005 Icon Editor problem
    Hi, I can add multiple icon (like 16 X 16, 32 X 32 etc.) in single ico file using VS2005 icon editor. But unable to find any way to change the selection from 32 X 32 to 16 X 16 or vice versa. I have to rely on VS6 for this. Is there any way to do this using VS2005 (may be there is some hidden option, I am not aware :)) ? I can not move to VS2008 because my company is still using VS2005 for main development. Regards, Manish Agarwal PS: This is first time I have to work on UI resources with VS2005 and this is second problem I faced with it (first one was toolbar button selection bug and there was no solution).
  • 2. Is it possible to view/open PropertySheet with PropertyPages in VS IDE ???
    Hi, I'm currently using a DDK based on MFC (VS 2005) to create a driver for a HMI software. The template project generated from the DDK has already included a PropertySheet with a PropertyPage. I'm trying to add another PropertyPage to the PropertySheet but it doesn't work out right. After adding the additional PropertyPage, the whole PropertySheet doesnt appear at all. Upon asking the DDK company, the support guy asked me whether I tried opening the PropertyPage in a normal PropertySheet in InitInstance of the DDK? I assume what he meant was that there is some way for me to view the PropertySheet with the PropertyPages in VS IDE??? Is it possible to do so? If i assumed wrongly, what did the support guy mean by that?? Please advise.

BSTR vs. _bstr_t

Postby Walter Eicher » Sat, 22 Aug 2009 19:26:20 GMT

Hello all,

I have to control a measurement application using COM. I'm not really
a COM specialist, so I'm amazed that most parts working perfectly ;-)

But a little detail I find suspect. 

The COM interface has a function for loading the setup file 
  
  void FileOpen (BSTR FAR* pbstrFileName);

If I do it like (1) then it works:

(1)
 BSTR newFile = SysAllocString (_T("Setup.qcc"));
 mSaunders250B->FileOpen (&newFile);
 SysFreeString (newFile);

If I do it like (2) then it does not work:

(2)
 _bstr_t newFile = _T("Setup.qcc");
 mSaunders250B->FileOpen (newFile.GetAddress ());

Of course I do it like (1), but after reading and (maybe wrong)
understanding, (2) should work also.

Someone out there who can bring light into the darkness?

Best regards
Walter Eicher





Re: BSTR vs. _bstr_t

Postby Goran » Sat, 22 Aug 2009 19:53:11 GMT

On Aug 21, 12:26m, Walter Eicher



Remark 0: not MFC!

Well... FileOpen seems bad per IDL rules (is this from *.idl, BTW,
or...?). That should be HRESULT FileOpen([in] BSTR FileName); in IDL
and HRESULT FileOpen(BSTR FileName) in *.h. (there's more detail in
there, but it's not relevant). This is because:

1. All COM methods should return HRESULT. If not, e.g. you will never
be able to marshal your interface, but there are probably other
issues.

2. Conceptually speaking, you should have BSTR, not BSTR* there,
because it's an input (or at least that's my guess). You should also
mark it as [in] then. On the client side, you should create a BSTR and
pass it (like in (1), but without "&"). In your server, you just use
it. If you need to keep it, you must make a copy (e.g. CString member;
member = FileName; works)

In general, it looks you should read more upon IDL and COM [in, out,
retval] rules with regard to memory management (I just caught this: ms-
help://MS.VSCC.v90/MS.MSDNQTR.v90.en/rpc/rpc/directional_parameter_attributes.htm).

On Aug 21, 12:26 pm, Walter Eicher


>>
>> If I do it like (1) then it works:
>>
>> (1)
>> STR newFile = SysAllocString (_T("Setup.qcc"));
>> Saunders250B>>FileOpen (&newFile);
>> ysFreeString (newFile);
>>
>> If I do it like (2) then it does not work:
>>
>> (2)
>> bstr_t newFile = _T("Setup.qcc");
>> Saunders250B>>FileOpen (newFile.GetAddress ());
>>

At the first glance, both should work. How does it "not work"?

What are you doing inside FileOpen? If you do *pbstrFileName = NULL,
that may be bad. Also, are you using #import, or are you including
MIDL-generated *.h?

HTH,
Goran.

Re: BSTR vs. _bstr_t

Postby Walter Eicher » Sat, 22 Aug 2009 20:25:20 GMT

Hi Goran,

On Fri, 21 Aug 2009 03:53:11 -0700 (PDT), Goran




Dont understand this!

I created the interface class with the wizard "MFC Class from TypeLib"
using the 250B.tlb bought from Saunders.

>>Well... FileOpen seems bad per IDL rules (is this from *.idl, BTW,
>>or...?). That should be HRESULT FileOpen([in] BSTR FileName); in IDL
>>and HRESULT FileOpen(BSTR FileName) in *.h. (there's more detail in
>>there, but it's not relevant). This is because:

>>At the first glance, both should work. How does it "not work"?

It does not load the setup file specified. 

Best regards
Walter




Re: BSTR vs. _bstr_t

Postby Goran » Sat, 22 Aug 2009 21:12:14 GMT

On Aug 21, 1:25m, Walter Eicher





Remark 0 meant: you ask much of an MFC question, or at least no
connection with MFC was visible from you first post (there is one if
you used MFC wizard, which you just said now).

Otherwise, I don't know. "it does not load file" is way to far from
the cause for said cause guess anything.

I don't know what would cause the wizard to use BSTR instead of
LPCTSTR (perhaps the use of BSTR __*__?), and that is strange. Perhaps
if you show *.idl of the *.tlb, using OleView?

It is also a bit unfortunate that MFC wizard-generated code basically
forces you to use non-MFC code (to get to an BSTR), but hey.

Goran.

Re: BSTR vs. _bstr_t

Postby Walter Eicher » Sat, 22 Aug 2009 22:43:47 GMT

Hi Goran,

On Fri, 21 Aug 2009 05:12:14 -0700 (PDT), Goran




Thanks for being with me ;-)

I think I found the cause why the _btsr_t version not works.

I stepped into the function FileOpen and the first hit was

  inline BSTR* _bstr_t::GetAddress ()
  {
     // here m_Data::m_wstr holds "Setup.qcc"
     Attach (0);
     // here mData::m_wstr holds 0x00000<BadPtr>
     return &m_Data->GetWString();
  }

  FileOpen is then called with a NULL pointer as BSTR* 

I dont know what for GetAddress is, but it seems its not for constant
strings.

Best regards
Walter



Re: BSTR vs. _bstr_t

Postby Joseph M. Newcomer » Sun, 23 Aug 2009 01:06:00 GMT

See below...
On Fri, 21 Aug 2009 12:26:20 +0200, Walter Eicher < XXXX@XXXXX.COM >



****
Do not use the word FAR in any declaration.  It is syntactic gibberish, left over from old
Win16 interfaces and Microsoft has failed to remove it from all definitions, leaving it
around to confuse people and generate cruft like the above declaration.  FAR is defined as

#define FAR

and as such, means that any use of it is meaningless noise.

The correct definition is

void FileOpen(BSTR * pbstrFileName);
****
****
 The use of _T() in SysAllocString is also incorrect, because there is no case of
SysAllocStringA/SysAllocStringW.  The documentation for SysAllocString *clearly* states 

"The sz parameter must be a Unicode string in 32-bit applications"

_T() does not conform to this requirement, except by accident.
****
****
Please define "does not work".  This description is without meaning.  Do you mean "It
fails to compile" or "it fails to link" or "it fails to run correctly and returns me an
HRESULT of <value here>" or "it fails to run correctly and causes an exception" or "it
fails to run correctly and <your description of observed value here>"?  How in the world
are we supposed to guess what you mean by "does not work"????
****
****
Note that the _bstr_t assignment using _T() works even in 8-bit apps because there is an
overloaded = operator for _bstr_t which accepts an 8-bit string.

However, the Microsoft documentation is not really clear on the difference between
GetAddress and GetBSTR; I suspect you should try it using GetBSTR.  I have read the code
of _bstr_t::GetAddress and _bstr_t::GetBSTR, and although the documentation does not state
it, the comments in the code say that GetAddress is used when the parameter is an "out"
parameter.  It appears that GetAddress sets the contents to NULL, although it is a bit
hard to track down; the Attach(0) in that code is suspiciously passing a NULL pointer to a
chain of other functions.  So it probably clears out the string.

I am adding these to my list of documentation failures.
				joe
****
Joseph M. Newcomer [MVP]
email:  XXXX@XXXXX.COM 
Web:  http://www.**--****.com/ 
MVP Tips:  http://www.**--****.com/ 

Re: BSTR vs. _bstr_t

Postby Joseph M. Newcomer » Sun, 23 Aug 2009 01:07:01 GMT

That is true; see my earlier note.
			joe

On Fri, 21 Aug 2009 15:43:47 +0200, Walter Eicher < XXXX@XXXXX.COM >




Joseph M. Newcomer [MVP]
email:  XXXX@XXXXX.COM 
Web:  http://www.**--****.com/ 
MVP Tips:  http://www.**--****.com/ 

Re: BSTR vs. _bstr_t

Postby Goran » Sun, 23 Aug 2009 03:32:14 GMT



Haha, true, but in all likelihood it's wizard-generated. MIDL output
is quite full of this noise, too. Not Walter's fault.


BTW, everyone, I just looked at the use-case for _bstr_t::GetAddress
here:  http://www.**--****.com/ (VS.80).aspx.
Well, that's one piece of clear design right there (not). It goes like
this:

bstr= SysAllocString(OLESTR("Yet another string"));
*bstrWrapper.GetAddress() = bstr;

Bwahahahahaaaaa...

So the purpose is to "assign" SysAlloc-ed BSTR to an existing _bstr_t,
without copying a BSTR. Obviously, to avoid leaks, _bstr_t is cleared
prior to emitting BSTR* of GetAddress. And it gets worse: since
_bstr_t is refcounted, this innocuous "Get" effectively changes the
value of all _bstr_t instances sharing underlying data.

I mean, seriously... Who, in the name of God, could even think this is
clear, or reasonable, is beyond me. And remark in GetAddress is
seriously useless: "GetAddress affects all _bstr_t objects that share
a BSTR. More than one _bstr_t can share a BSTR through the use of the
copy constructor and and operator=." Erm... It's a "Get". Why the hell
does it affect anything!? Is the absence of "const" qualifier supposed
to be a hint?

You know what?

_bstr_t::ReplaceUnderlyingBSTROfAllInstancesSharingUnderlyingData(BSTR
in)

would have been more clear.

These MS people are funny.

In any case, the mystery is cleared: GetAdress cleared the string,
passing NULL to FileOpen, FileOpen failed due to NULL input.
GetAddress wasn't used to "set" the thing it is supposed to set,
Walter thought that Get doesn't mean "Set". Uh-oh, my stomach...

I had a tough day at work, but this just turned it around.

Goran.

Re: BSTR vs. _bstr_t

Postby Joseph M. Newcomer » Sun, 23 Aug 2009 04:23:11 GMT

Not only are all your comments about the poor quality of the documentation dead on, but
the EXAMPLE SHOWN DOES NOT EXECUTE CORRECTLY!   It clobbers the string then takes a memory
access exception.  I'm in the middle of documenting this piece of rubbish.  Look for it in
my MSDN Errors and Omissions, probably sometime this evening.  It brings my count of bad
pages in the MSDN to 421 (so much for the twit earlier this week that claimed that
codeproject was amateur code with lots of errors, but the MSDN site was perfect!)

Note that this count is almost certainly horribly low, since it only covers what I've
*discovered*, or others have been confused by and reported in this newsgroup, or which
have been sent to me by private email!

The _bstr_t documentation was written by someone who was totally clueless.  I'm sure if I
read more of it, I'd find other ridiculous errors.  Most of it is incomprehensible at
worst, and it appears that it was *designed* to be confusing and misleading!
				joe






Joseph M. Newcomer [MVP]
email:  XXXX@XXXXX.COM 
Web:  http://www.**--****.com/ 
MVP Tips:  http://www.**--****.com/ 

Re: BSTR vs. _bstr_t

Postby Joseph M. Newcomer » Sun, 23 Aug 2009 09:25:12 GMT

I'm on hiatus on my current project this afternoon (waiting for client feedback from this
morning's drop) so I took time to write about the _bstr_t types, at least about the
assignment, GetBSTR and GetAddress issues.  There may be other problems which I did not
examine.  Given the overalll quality of the documentation I examined, there are probably
many other failures in the documentation.

As I stated in an earlier message, the Microsoft example is broken AND DOES NOT WORK.  It
crashes with an access fault.

I created some example code that demonstrates that (a) the talk about shared BSTRs is
gibberish, because it is vague, confusing, and wrong (b) GetAddress does not affect shared
BSTRs (c) GetBSTR on the LHS of an assignment *does* affect shared BSTRs.  

The documentation is just a mess.  

See a discussion of the BSTR sharing problems under

 http://www.**--****.com/ #_bstr_t::Assign

				joe


On Fri, 21 Aug 2009 12:26:20 +0200, Walter Eicher < XXXX@XXXXX.COM >



Joseph M. Newcomer [MVP]
email:  XXXX@XXXXX.COM 
Web:  http://www.**--****.com/ 
MVP Tips:  http://www.**--****.com/ 

Re: BSTR vs. _bstr_t

Postby Walter Eicher » Tue, 25 Aug 2009 16:54:31 GMT

Ho Joe,

On Fri, 21 Aug 2009 12:06:00 -0400, Joseph M. Newcomer




Sorry for this, but in the heat of the battle sometimes I loose my
head ;-)

Best regards
Walter


Similar Threads:

1.BSTR, _bstr_t issues occuring on our Windows 2003 Server

We have server components which were created by a third party and
compiled in VC++5 (sp3). They run fine on NT4 and 2000, however during
testing of our migration to Server 2003, these components have been
failing when performing Data Access functions. In particular we have
been having problems with BSTR and _bstr_t.

_bstr_t(BSTR*, 1) is the original code that the problem started with.
Other findings are -

1) Converting a BSTR* to a _bstr_t when the length of the message in
BSTR* is 16,382 characters or more, gives errors.
a) Using _bstr_t(BSTR*, 1) causes the application to crash. fcopy=1
b) Using _bstr_t(BSTR*) ). In this case, fcopy=0 by default.
i) When message length is 16,382 or more characters - converts the
message but the first two characters are corrupted and unreadable
ii) When message length is much higher, ex:32,758 characters, the
application crashes.
2) The length of message content is not an issue when converting
_bstr_t to a BSTR.

_bstr_t(BSTR*, 1) worked fine even for message lengths as high as
50,292 characters, on the Windows NT 4.0 and Windows 2000 servers.

Anyone have any advice, input?

2.interfacing between BSTR, LPCTSTR, CComBSTR, _bstr_t

Argh. I keep running into this.
Often I have a case where I have a COM method that has an [out]
parameter which returns a BSTR *. Then I have to store the results
somewhere in a variable of my own choosing. Then I have to use this
variable as an input to a Win32 function which takes LPCTSTR.

I notice that CComBSTR can be used with the COM method but _bstr_t
cannot, e.g.:
CComBSTR b1;
_bstr_t b2;
pComObject->Something(&b1); // works
pComObject->Something(&b2); // won't work

Also CComBSTR has Attach() and Detach() members to allow you to
control ownership w/o having to duplicate memory. But _bstr_t does
not. :(

I also notice that _bstr_t has the facilities to convert to a char *
if necessary, but CComBSTR does not. So _bstr_t is better for use
where a function might require a LPCTSTR or a char *. And _bstr_t uses
reference counting to allow sharing memory between _bstr_t; very
useful for STL containers where contained items get copied a lot.

I therefore end up doing stuff like this a lot:
CComBSTR btemp; // short term storage
_bstr_t b; // long term storage, usually a member of a class
pComObject->Something(&btemp);
b = btemp; // store it for long term use.
...
SomeRandomWin32Function(b);

This seems (slightly) wasteful to have to use the CComBSTR in this
way; I would really like to skip this step.

Is there any way to get a _bstr_t to use the [out] parameter of a COM
method without copying the string?

[p.s. I am using VC6, has this been improved in later editions of the
compilers?]

3.BSTR, _bstr_t, std::wstring

I am writing a COM object, and I would like to keep track of strings
internally via std::wstring.  I have hit upon the following scheme for
get/put methods exposed to the outside world.  I'm more or less new to
COM programming, so I would appreciate any comments - especially if
I'm doing something incorrectly, but also if I can do something in a
more efficient and/or more clean manner.

   std::wstring m_X;

   STDMETHODIMP CSequence::get_X(BSTR *pVal)
   {
      USES CONVERSION;
      BSTR bstr = W2BSTR ( m_X.c_str() );
      _bstr_t bstrt = _bstr_t();
      bstrt.Attach ( bstr );
      *pVal = bstrt.copy();
      bstrt.Detach();	

      return S_OK;
   }

   STDMETHODIMP CSequence::put_X(BSTR newVal)
   {
      m_X = wstring ( newVal );

      return S_OK;
   }

Thanks in advance for any help.

Bob Vesterman.
-- 
This is the coolest of all sig files.

4.CComBSTR, _bstr_t and BSTR*

Hi All,

I have a question about the 2 bstr types _bstr_t and CComBSTR and
calling get_ methods that take a BSTR*.

The CComBSTR has an & operator which is quite handy so I've been using
this as follows:

CComBSTR bstrVal;
pFoo->GetString(&bstrVal); // Takes a BSTR*

Now I want to convert it to _bstr_t, is this legal (i.e. are there any
issues I ned to be concerned about)..

_bstr_t bstrAnother = bstrVal;

Is there a better way to do this?

If only this were legal..

_bstr_t bstrTmp;
pFoo->GetString(&bstrTmp);

Thanks.

5.BSTR and _bstr_t

Whats the difference between a BSTR and _bstr_t.I know its a
wrapper.But is it correct way to use both in following manner

BSTR bstrNewFileName = _bstr_t("xyz.htm");
BSTR str = szCString.AllocSysString();
ATLFunctionCall(str,bstrNewFileName);

I YES Then When i make a ATLFunction call to another Module then the
value of bstrNewFileName inside the other Module changes to that of
"str"(see function call).Can anyone tell me y this happens.

Also if NO then y and which would be the right way.


cheers,
Sada

6. BSTR, _bstr_t, and CComBSTR and memory leaks....

7. BSTR and _bstr_t with #import

8. howto determine memory leaks for _bstr_t and BSTR



Return to VC

 

Who is online

Users browsing this forum: No registered users and 82 guest