473,395 Members | 1,452 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,395 software developers and data experts.

How do I retrun a BSTR from C++ to VB.NET

I have a C++ function in a DLL of the form

BSTR WINAPI DoSomeWork(LPCSTR szConnection, LPCSTR szGUID)

I use SysAllocStringByteLen to return a BSTR.

For the most part this works accept when the calling applicaiton tries to
free the BSTR and I get a RtlFreeHeep error. I'm guessing because the bstr
has been allocated in one dll and it being released in another.

So how do I allocate the bstr that I'm returning ?
--
Michael Tissington
http://www.oaklodge.com
http://www.tabtag.com

Nov 21 '05 #1
8 5173
"Michael Tissington" <mi*****@nospam.com> wrote in message
news:ed****************@TK2MSFTNGP10.phx.gbl...
I have a C++ function in a DLL of the form

BSTR WINAPI DoSomeWork(LPCSTR szConnection, LPCSTR szGUID)

I use SysAllocStringByteLen to return a BSTR.

For the most part this works accept when the calling applicaiton tries to
free the BSTR and I get a RtlFreeHeep error. I'm guessing because the bstr
has been allocated in one dll and it being released in another.

So how do I allocate the bstr that I'm returning ?


Does the calling app use SysFreeString? Can you show and example of how
determine the byte length to allocate and how you subsequently fill the
BSTR?
--
Jeff Partch [VC++ MVP]
Nov 21 '05 #2
I have no idea what the calling app does (it can be either a VB 6 or VB.NET
application) to free the string.

This is how I declare it in VB 6

Public Declare Function DoSomeWork Lib "Work.dll" (ByVal strConnection As
String, ByVal strGUID As String) As String

And this is how I fill it (not that I think this is of much help)

BSTR bstrEntryID = NULL;
......
bstrEntryID = SysAllocStringByteLen(NULL, (sizeof(SQLVIEW_ENTRYID) * 2) +
1);
HexFromBin((LPBYTE)&eid, sizeof(SQLVIEW_ENTRYID), (LPSTR)bstrEntryID);
return bstrEntryID

Both VB and VB.NET seem to get the string correctly and are able to work
with it.

Its just that I get the RtlFreeHeep error in VB.NET when it uses this
funciton.

--
Michael Tissington
http://www.oaklodge.com
http://www.tabtag.com
"Jeff Partch [MVP]" <je***@mvps.org> wrote in message
news:%2****************@tk2msftngp13.phx.gbl...
"Michael Tissington" <mi*****@nospam.com> wrote in message
news:ed****************@TK2MSFTNGP10.phx.gbl...
I have a C++ function in a DLL of the form

BSTR WINAPI DoSomeWork(LPCSTR szConnection, LPCSTR szGUID)

I use SysAllocStringByteLen to return a BSTR.

For the most part this works accept when the calling applicaiton tries to
free the BSTR and I get a RtlFreeHeep error. I'm guessing because the
bstr
has been allocated in one dll and it being released in another.

So how do I allocate the bstr that I'm returning ?


Does the calling app use SysFreeString? Can you show and example of how
determine the byte length to allocate and how you subsequently fill the
BSTR?
--
Jeff Partch [VC++ MVP]

Nov 21 '05 #3
"Michael Tissington" <mi*****@nospam.com> wrote in message
news:%2****************@tk2msftngp13.phx.gbl...
I have no idea what the calling app does (it can be either a VB 6 or VB.NET application) to free the string.

This is how I declare it in VB 6

Public Declare Function DoSomeWork Lib "Work.dll" (ByVal strConnection As
String, ByVal strGUID As String) As String

And this is how I fill it (not that I think this is of much help)

BSTR bstrEntryID = NULL;
.....
bstrEntryID = SysAllocStringByteLen(NULL, (sizeof(SQLVIEW_ENTRYID) * 2) +
1);


Try making that +1 a +2, just for the heck of it. :)

--
Jeff Partch [VC++ MVP]

Nov 21 '05 #4
Nice idea but unfortunately it does not help the situation.

--
Michael Tissington
http://www.oaklodge.com
http://www.tabtag.com
"Jeff Partch [MVP]" <je***@mvps.org> wrote in message
news:%2***************@TK2MSFTNGP15.phx.gbl...
"Michael Tissington" <mi*****@nospam.com> wrote in message
news:%2****************@tk2msftngp13.phx.gbl...
I have no idea what the calling app does (it can be either a VB 6 or

VB.NET
application) to free the string.

This is how I declare it in VB 6

Public Declare Function DoSomeWork Lib "Work.dll" (ByVal strConnection As
String, ByVal strGUID As String) As String

And this is how I fill it (not that I think this is of much help)

BSTR bstrEntryID = NULL;
.....
bstrEntryID = SysAllocStringByteLen(NULL, (sizeof(SQLVIEW_ENTRYID) * 2) +
1);


Try making that +1 a +2, just for the heck of it. :)

--
Jeff Partch [VC++ MVP]

Nov 21 '05 #5
On 2005-07-08, Michael Tissington <mi*****@nospam.com> wrote:
I have a C++ function in a DLL of the form

BSTR WINAPI DoSomeWork(LPCSTR szConnection, LPCSTR szGUID)

I use SysAllocStringByteLen to return a BSTR.

For the most part this works accept when the calling applicaiton tries to
free the BSTR and I get a RtlFreeHeep error. I'm guessing because the bstr
has been allocated in one dll and it being released in another.

So how do I allocate the bstr that I'm returning ?


Ok... I believe to deallocate a buffer created with
SysAllocStringByteLen, that you need to deallocate that memory with
SysFreeString. Marshal.FreeBSTR will do this... What you may want to do
is wrap this call in a function that returns a managed string.

Maybe this would work... Though, I'm not sure since I haven't worked a
lot with BSTR in .NET.

Private Declare Function DoSomeWork Lib "whatever" _
(ByVal szConnection As String, _
ByVal szGuid As String) As IntPtr
Public Function DoSomeWorkWrapper _
(ByVal Connection As String, ByVal id As Guid) As String

Dim bstrPtr As IntPtr = IntPtr.Zero
Try

' you might need to manipulate the guid string some what,
' since I'm not sure what format your function needs it in :)
bstrPtr = DoSomeWork (Connection, id.ToString())

// return a managed string from the unmanaged bstr
Return Marshal.PtrToStringBSTR (bstrPtr)

Finally
If Not bstrPtr.Equals (IntPtr.Zero) Then
Marshal.FreeBSTR (bstrPtr)
End If
End Try
End Function

Anyway, that may or may not work. Otherwise, you'll need to pin the
object get the pointer, and then call FreeBSTR that way. But, anyway
you look at it - RtlFreeHeap probably can't deallocate the memory used
by the BSTR.

--
Tom Shelton [MVP]
Nov 21 '05 #6
>Maybe this would work... Though, I'm not sure since I haven't worked a
lot with BSTR in .NET.

Private Declare Function DoSomeWork Lib "whatever" _
(ByVal szConnection As String, _
ByVal szGuid As String) As IntPtr

The runtime should do the right thing if you declare it as

Private Declare Function DoSomeWork Lib "whatever" _
(ByVal szConnection As String, _
ByVal szGuid As String) As
<MarshalAs(UnmanagedType.AnsiBStr)> String

I don't think Marshal.PtrToStringBSTR would work here as the string
was allocated with SysAllocStringByteLen and contains ANSI characters.


Mattias

--
Mattias Sjögren [MVP] mattias @ mvps.org
http://www.msjogren.net/dotnet/ | http://www.dotnetinterop.com
Please reply only to the newsgroup.
Nov 21 '05 #7
In article <u8**************@TK2MSFTNGP09.phx.gbl>, Mattias Sjögren wrote:
Maybe this would work... Though, I'm not sure since I haven't worked a
lot with BSTR in .NET.

Private Declare Function DoSomeWork Lib "whatever" _
(ByVal szConnection As String, _
ByVal szGuid As String) As IntPtr

The runtime should do the right thing if you declare it as

Private Declare Function DoSomeWork Lib "whatever" _
(ByVal szConnection As String, _
ByVal szGuid As String) As
<MarshalAs(UnmanagedType.AnsiBStr)> String

I don't think Marshal.PtrToStringBSTR would work here as the string
was allocated with SysAllocStringByteLen and contains ANSI characters.


You are most likely correct... I looked up Marshal.FreeBSTR, and it
doesn't mention SysAllocStringByteLen - yet, the documentation for
SysFreeString does.

Oh, well. Like I said - I haven't really had to do much with BSTR since
I moved to .NET. So, take my advice with a grain of salt.

To the OP - listen to Mattias, he is the interop guru :)

--
Tom Shelton [MVP]
Nov 21 '05 #8
Thanks - just what I was looking for.

--
Michael Tissington
http://www.oaklodge.com
http://www.tabtag.com
"Mattias Sjögren" <ma********************@mvps.org> wrote in message
news:u8**************@TK2MSFTNGP09.phx.gbl...
Maybe this would work... Though, I'm not sure since I haven't worked a
lot with BSTR in .NET.

Private Declare Function DoSomeWork Lib "whatever" _
(ByVal szConnection As String, _
ByVal szGuid As String) As IntPtr

The runtime should do the right thing if you declare it as

Private Declare Function DoSomeWork Lib "whatever" _
(ByVal szConnection As String, _
ByVal szGuid As String) As
<MarshalAs(UnmanagedType.AnsiBStr)> String

I don't think Marshal.PtrToStringBSTR would work here as the string
was allocated with SysAllocStringByteLen and contains ANSI characters.


Mattias

--
Mattias Sjögren [MVP] mattias @ mvps.org
http://www.msjogren.net/dotnet/ | http://www.dotnetinterop.com
Please reply only to the newsgroup.

Nov 21 '05 #9

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

Similar topics

1
by: Chris | last post by:
I am not sure if this is the right newsgroup. But does anyone know what is the difference between a BSTR and a LPOLESTR? The only thing I could find out is that the advantage of taking BSTR...
2
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
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...
0
by: Edwin Knoppert | last post by:
I'm currently using a wrapper which converts an ANSI BSTR from a dll. (Yes, singlebyte but BSTR ! ) This works fine and i'm aware BSTR's returned must be destroyed by the caller, which i do. ...
5
by: bluter | last post by:
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...
37
by: Egbert Nierop \(MVP for IIS\) | last post by:
In win32 mode, a BSTR was UINT length prefixed and terminated exactly by a zero char. So if you allocated "Hello World" that would allocate 28 bytes. In x64 and (IA64 as well) it would become...
2
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...
0
by: Jason Smiley | last post by:
So I have a function that is called from a COM object that has a BSTR as an out paramater. A code snippet looks like this: MyComLib.MyComInterface tester = new MyComLib.MyComInterface(); // ...
2
by: mzdude | last post by:
I need to interface with a windows DLL that has the following signature extern "C" void Foo( BSTR in, BSTR *out ) Code so far Traceback (most recent call last): File "<pyshell#14>", line...
0
by: ryjfgjl | last post by:
In our work, we often receive Excel tables with data in the same format. If we want to analyze these data, it can be difficult to analyze them because the data is spread across multiple Excel files...
0
by: emmanuelkatto | last post by:
Hi All, I am Emmanuel katto from Uganda. I want to ask what challenges you've faced while migrating a website to cloud. Please let me know. Thanks! Emmanuel
0
BarryA
by: BarryA | last post by:
What are the essential steps and strategies outlined in the Data Structures and Algorithms (DSA) roadmap for aspiring data scientists? How can individuals effectively utilize this roadmap to progress...
1
by: Sonnysonu | last post by:
This is the data of csv file 1 2 3 1 2 3 1 2 3 1 2 3 2 3 2 3 3 the lengths should be different i have to store the data by column-wise with in the specific length. suppose the i have to...
0
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...
0
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers,...
0
jinu1996
by: jinu1996 | last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven...
0
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...
0
tracyyun
by: tracyyun | last post by:
Dear forum friends, With the development of smart home technology, a variety of wireless communication protocols have appeared on the market, such as Zigbee, Z-Wave, Wi-Fi, Bluetooth, etc. Each...

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.