Yaron Naveh
Yaron Naveh

Reputation: 24406

CComBSTR memory allocation

I have a "const char* str" with a very long string. I need to pass it from a cpp client to a .Net COM method which expects BSTR type. Currently I use:

CComBSTR bstr = str;

This has the following issues:

Questions:

Any other suggestion is also welcomed...

Upvotes: 0

Views: 2363

Answers (3)

sharptooth
sharptooth

Reputation: 170489

If a method is expecting a BSTR passing a BSTR is the only correct way.

To convert char* to a BSTR you use MultiByteToWideChar() Win32 API function for conversion and SysAllocStringLen() for memory allocation. You can't get around that - you need SysAllocStringLen() for memory allocation because otherwise the COM server will fail if it calls SysStringLen().

When you use CComBSTR and assign a char* to it the same sequence is run - ATL is available as headers and you can enjoy reading it to see how it works. So in fact CComBSTR does exactly the minimal set of necessary actions.

When you pass a BSTR to a COM server CComBSTR::operator BSTR() const is called that simply returns a pointer to the wrapped BSTR - the BSTR body is not copied. Anything that happens next is up to the COM server or the interop being used - they decide for themselves whether they want to copy the BSTR body or just read it directly.

Your only bet for resolving the memory outages is to change the COM interface so that it accepts some reader and requests the data in chunks through that reader.

Upvotes: 3

Shay Erlichmen
Shay Erlichmen

Reputation: 31928

Is it an In-Process COM server do you have the code for it or is it a 3rd party? because you can pass the actual char* pointer to the COM server and not pay the price of allocate+copy+free. You will need to add a new method/property that will be available only to C++ clients.


Instead of passing BSTR you can wrap your char* in a Stream interface, the .NET server should get a Stream instead of a string.

On the C++ side implement a COM class that support the IStream COM interface, this class is a read only stream which wraps the char*, you can pass this class as UCOMIStream interface to the .NET server.
On the .NET side use the UCOMIStream methods to read the string, be careful not to read the entire stream in one pass.

Upvotes: 1

Steve Gilham
Steve Gilham

Reputation: 11277

A CComBSTR is a wrapper around a BSTR which in turn is counted Unicode string with special termination.

You would thus expect it to be about twice the size of the corresponding char* form (for character sets that mainly use single-byte characters).

Using a CComBSTR is a good idea in general, since the destructor will free the memory associated with the BSTR for you.

Upvotes: 0

Related Questions