473,796 Members | 2,740 Online
Bytes | Software Development & Data Engineering Community
+ Post

Home Posts Topics Members FAQ

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?

Mar 10 '06 #1
5 2664
bluter wrote:
_bstr_t(BSTR*, 1) is the original code that the problem started with.


are you sure you are using BSTR* (that is pointer to BSTR)? This is
wrong, _bstr_t is abstraction for BSTR which in itself is a pointer
(without an extra pointer). Futhermore, if you happen to mix wchar_t*
with BSTR, you may NOT pass wchar_t* where BSTR is expected, because
BSTR is expected to be prefixed with length (and wchar_t* is just a
pointer, with no magic, that is no prefix). And if you happen to pass
BSTR as a result of function, be very, very careful not to leak it or
double free; or simply replace it with _bstr_t to keep things tidy.
B.
Mar 10 '06 #2
We are using BSTR and it is being passed back as a result of a
function. This is all over the project and the way it is setup, it is
close to impossible for changing it.
We do suspect that there is a leak occurring during at the time the
result is being passed back from the lower function to the calling
function. This happens in Windows 2003 server and was not an issue in
Windows NT 4.0 or Windows 2000 servers. Are you aware of similar issues
with VC++5.0 applications running on Windows 2003 servers?
Could you suggest ways to prevent leaks/double free when BSTR is passed
back as result of a function.

Code shown below:

const string FMLMsgProxy::ge tMsg ()
{
BSTR bstrMsg = m_pFINMsg->getMsg();
_bstr_t bstrtMsg(bstrMs g); //Code breaks here
------------------
---------------
}

STDMETHODIMP CFINMsg::getMsg (BSTR * o_Msg)
{
--------------------------------
-----------------------------
*o_Msg = m_OGMsg.copy(); //m_OGMsg is declared as _bstr_t
return S_OK;
}

Mar 14 '06 #3
su************* *@gmail.com wrote:
We do suspect that there is a leak occurring during at the time the
no, but you might have a leak somewhere else, as you apparently do not
understand some things about _bstr_t and BSTR. And you have other
problems, described below.
const string FMLMsgProxy::ge tMsg ()
{
BSTR bstrMsg = m_pFINMsg->getMsg();
_bstr_t bstrtMsg(bstrMs g); //Code breaks here
I assume that getMsg (as called above) is actually wrapper provided by
compiler COM support, that is #import and accompanying *.tlh and *.tli
files. The wrapper funtion returns temporary object of type _bstr_t .
Just after initialization of BSTR bstrMsg this temporary object is
destroyed, and memory pointed by bstrMsg is freed by _bstr_t destructor.
Thus in next line bstrMsg is just a dangling pointer. This is why you
have crash.

Instead you should just use:

_bstr_t bstrtMsg = m_pFINMsg->getMsg();

If, on the other hand, getMsg() is not a wrapper and is *really*
returning a BSTR (not _bstr_t ), then you have a memory leak (but then
program wouldn't crash). Initialization of _bstr_t from BSTR will make a
copy and NOT take ownership of the string, unless you pass false as
second argument of constructor (that is fCopy, as documented in MSDN) -
in which case _bstr_t will take ownership of returned BSTR. If you just
use implicit conversion from BSTR to _bstr_t, you actually make a copy
of BSTR returned by COM function (instead of taking ownership), probably
no-one will free this BSTR and you have a leak.
STDMETHODIMP CFINMsg::getMsg (BSTR * o_Msg)
{
--------------------------------
-----------------------------
*o_Msg = m_OGMsg.copy(); //m_OGMsg is declared as _bstr_t
return S_OK;


If your function is returning a string (that is "[OUT, RETVAL] BSTRT *"
), you should pass ownership of _bstr_t . For this operation use
Detach(), not copy(). It's not that copy() or copy(true) are bad (they
aren't), but if you happen to call by mistake copy(false) or just
perform implicit converion from _bstr_t to BSTR, you will again end up
with dangling pointer. On the other hand, copy(true) is safe, but is
also wasting CPU cycles, as it allocates new string unnecessarily.
Obviously, caller of your function is resposible for freeing BSTR
returned as [OUT, RETVAL], but this is mandated by COM and provided by
COM wrappers (that is #import , *.tlh and *.tli files) so you do not
have to worry - if you use these COM wrappers properly.

I suggest that you buy this book
http://www.amazon.com/gp/product/0735611270/ (and I mean this one, not
any other - it's out of print, but there are still copies available) and
read first 3 chapters very, very carefully. At least twice. You would
benefit from other good books on COM, too.
B.
PS. some samples:

#include <comdef.h>

// fragile, caller might leak returned BSTR
BSTR foo() {_bstr_t t = L"foo"; return t.Detach();}

// fragile and unnecessary overhead making a copy
BSTR bar() {_bstr_t t = L"bar"; return t.copy();}

// very bad, returning dangling pointer
BSTR boo() {_bstr_t t = L"boo"; return t.copy(false);}

// very bad, just like boo, as operator BSTR is equiv. to copy(false)
BSTR bam() {_bstr_t t = L"bam"; return t;}

// reliable, like code provided by COM wrappers
_bstr_t bow() {_bstr_t t = L"bow"; return t;}

int main()
{
_bstr_t t(foo(), false); // OK, but fragile
_bstr_t t1 = bar(); // memory leak!
_bstr_t t2 = boo(); // crash!
_bstr_t t3 = bam(); // crash!
_bstr_t t4 = bow(); // OK and reliable
BSTR t5 = bow(); // potential trap ...
_bstr_t t6 = t5; // ... and crash!
}
obviusly, actual crash might or might not happen, depending on compiler
version, compilation options, sorrounding code etc - using dangling
pointer is always bad, however it may not always result in immediate
crash - often you will just see "bad" results, and sometimes you will
not even notice that you have a problem. This especially applies to
small sample app. that actually does nothing, just like the one above.

Mar 14 '06 #4
B. wrote:
Instead you should just use:

_bstr_t bstrtMsg = m_pFINMsg->getMsg();


The code was changed to capture the BSTR into a _bstr_t wrapper and
application(s) works as expected - from what was seen in our initial
tests. The code extract that was changed is below -

const string FMLMsgProxy::ge tMsg ()
{
//BSTR bstrMsg = m_pFINMsg->getMsg(); // the code before
_bstr_t bstrtMsg = m_pFINMsg->getMsg(); // code after change
-------------------
--------------
}

Thanks a million ton for the informational post.

Sunita

Mar 15 '06 #5
su************* *@gmail.com wrote:
//BSTR bstrMsg = m_pFINMsg->getMsg(); // the code before
_bstr_t bstrtMsg = m_pFINMsg->getMsg(); // code after change
good.
Thanks a million ton for the informational post.


you are welcome. Pardon my conceited tone, but I suggest that you review
whole application seeking for similar mistakes. Regards
B.
Mar 15 '06 #6

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

5
48705
by: Karthik | last post by:
Hello, How can I convert a BSTR data type to std::string??? Thanks a much! Karthik
2
5074
by: banski | last post by:
Hi, Im trying to find out how to convert a SYSTEMTIME to BSTR. Cant find out how to do that. Hopefully some of you could help me out. Best regards Thomas
7
7127
by: Gilad Walden | last post by:
I use C# in .NET framework. I have an ActiveX implemented in C++ that has a COM interface method that gets as it’s out parameter a BSTR* . The interop translates this BSTR* into C# string. From my managed code, I am calling that function with ‘out’ parameter of ‘string’ type. For normal size strings it works fine, but when the string is very big (> 50,000 bytes), I get a null exception from the COM interop. What is the reason?...
0
993
by: Digifox | last post by:
Below is a class method that puts a new string in place of the old one! I am new to this environment! But if I am in the write area to begin with! I am trying to iterate thru the string passed to this method! Encrypt it and put it back into newVal. Maybe a for/next or loop here around newVal. I would like to rebuild the string(newVal)
0
1127
by: Digifox | last post by:
I am new to this environment! But if I am in the write area to begin with! In my atl dll I am creating a functions that pass information back and forth to access, vb and csharp. I am trying to iterate thru the string put here, newVal. I want to loop thru a variable length string and rebuild an encrypted string that gets passed back to newVal. Maybe a for or loop statement around newVal. I would like to rebuild the string(newVal)
10
3096
by: Robert | last post by:
I have an app that was originally 1.1, now migrated to 2.0 and have run into some sporadic viewstate errors...usually saying the viewstate is invalid, eventvalidation failed or mac error. My web config does specify a machinekey setting: <machineKey validationKey="447C05E8B3A71401CC4CAE5513A7F1A3494A3618EE819316AAD1D58433F236A759D66FB4154500E01EB4E1BC1DE42046E2D652D391CB8367A1649438867A02EB"...
4
5369
by: joseph_mueller | last post by:
I have a BSTR something like this firstHalf.secondHalf I want to parse this string using the "." as the delimeter, so I will end up with two different BSTRs, one for the stuff before the "." and one for the stuff after it. How can I do this?
4
6104
by: Abubakar | last post by:
Hi, Lets say I write this line: BSTR b = m_pdoc->Getxml (); where m_pdoc is MSXML2::IXMLDOMDocumentPtr. Now "b" contains the xml text. When I exit the function in which this line is written, do I have to take care about deleting "b"? And how do I do it ? Regards,
2
1543
by: Lucy Ludmiller | last post by:
How can I write a function like this: BSTR Greeting(BSTR name) { //return "Good Morning : " + name ; } In short I'm looking for a quick tutorial on using BSTR - Google is not bringing up anything consise enough (I'm not particularly interested in the history of BSTR and the differences between string types etc ...
0
9685
marktang
by: marktang | last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However, people are often confused as to whether an ONU can Work As a Router. In this blog post, we’ll explore What is ONU, What Is Router, ONU & Router’s main usage, and What is the difference between ONU and Router. Let’s take a closer look ! Part I. Meaning of...
0
9535
by: Hystou | last post by:
Most computers default to English, but sometimes we require a different language, especially when relocating. Forgot to request a specific language before your computer shipped? No problem! You can effortlessly switch the default language on Windows 10 without reinstalling. I'll walk you through it. First, let's disable language synchronization. With a Microsoft account, language settings sync across devices. To prevent any complications,...
1
10201
by: Hystou | last post by:
Overview: Windows 11 and 10 have less user interface control over operating system update behaviour than previous versions of Windows. In Windows 11 and 10, there is no way to turn off the Windows Update option using the Control Panel or Settings app; it automatically checks for updates and installs any it finds, whether you like it or not. For most users, this new feature is actually very convenient. If you want to control the update process,...
0
9061
agi2029
by: agi2029 | last post by:
Let's talk about the concept of autonomous AI software engineers and no-code agents. These AIs are designed to manage the entire lifecycle of a software development project—planning, coding, testing, and deployment—without human intervention. Imagine an AI that can take a project description, break it down, write the code, debug it, and then launch it, all on its own.... Now, this would greatly impact the work of software developers. The idea...
1
7558
isladogs
by: isladogs | last post by:
The next Access Europe User Group meeting will be on Wednesday 1 May 2024 starting at 18:00 UK time (6PM UTC+1) and finishing by 19:30 (7.30PM). In this session, we are pleased to welcome a new presenter, Adolph Dupré who will be discussing some powerful techniques for using class modules. He will explain when you may want to use classes instead of User Defined Types (UDT). For example, to manage the data in unbound forms. Adolph will...
0
5582
by: adsilva | last post by:
A Windows Forms form does not have the event Unload, like VB6. What one acts like?
1
4130
by: 6302768590 | last post by:
Hai team i want code for transfer the data from one system to another through IP address by using C# our system has to for every 5mins then we have to update the data what the data is updated we have to send another system
2
3744
muto222
by: muto222 | last post by:
How can i add a mobile payment intergratation into php mysql website.
3
2931
bsmnconsultancy
by: bsmnconsultancy | last post by:
In today's digital era, a well-designed website is crucial for businesses looking to succeed. Whether you're a small business owner or a large corporation in Toronto, having a strong online presence can significantly impact your brand's success. BSMN Consultancy, a leader in Website Development in Toronto offers valuable insights into creating effective websites that not only look great but also perform exceptionally well. In this comprehensive...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.