473,806 Members | 2,284 Online
Bytes | Software Development & Data Engineering Community
+ Post

Home Posts Topics Members FAQ

problem in accessing a BSTR* from C#

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? How to solve this problem?

Thanks in advance.
Nov 17 '05 #1
7 7128
Hey Gilad,

Try using MarhsalAs attribute ont the function with BSTR.

Refer to MSDN for further information on the MarshalAs attribute.

-Moty-

"Gilad Walden" <Gi*********@di scussions.micro soft.com> wrote in message
news:44******** *************** ***********@mic rosoft.com...
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? How to solve this problem?

Thanks in advance.

Nov 17 '05 #2
But the Interop wrapper to the ActiveX is created automatically by VS.NET
when we drag the ActiveX into a form. we have no control on how it is being
done.

"Moty Michaely" wrote:
Hey Gilad,

Try using MarhsalAs attribute ont the function with BSTR.

Refer to MSDN for further information on the MarshalAs attribute.

-Moty-

"Gilad Walden" <Gi*********@di scussions.micro soft.com> wrote in message
news:44******** *************** ***********@mic rosoft.com...
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? How to solve this problem?

Thanks in advance.


Nov 17 '05 #3
Are you sure the ActiveX component is designed to deal with that large BSTR?

Willy.

"Gilad Walden" <Gi*********@di scussions.micro soft.com> wrote in message
news:44******** *************** ***********@mic rosoft.com...
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? How to solve this problem?

Thanks in advance.

Nov 17 '05 #4
I have tested it with an Un-managed client (MFC) and exactly the same string
that crashes .Net works fine in the MFC client.

"Willy Denoyette [MVP]" wrote:
Are you sure the ActiveX component is designed to deal with that large BSTR?

Willy.

"Gilad Walden" <Gi*********@di scussions.micro soft.com> wrote in message
news:44******** *************** ***********@mic rosoft.com...
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? How to solve this problem?

Thanks in advance.


Nov 17 '05 #5

"Gilad Walden" <Gi*********@di scussions.micro soft.com> wrote in message
news:74******** *************** ***********@mic rosoft.com...
I have tested it with an Un-managed client (MFC) and exactly the same
string
that crashes .Net works fine in the MFC client.

Maybe you should post your code, anyway, this works for me...

//C++

STDMETHODIMP CNoReg::GetLarg eString(BSTR* large){
const int buffSize = 65000;
wchar_t* pwStr = new wchar_t[buffSize];
wmemset(pwStr, 0, buffSize);
// Fill with all 'A', leave room for null char.
for (int i = 0;i < buffSize-1; i++)
pwStr[i] = L'A';
try {
CAtlString s(pwStr);
*large = s.AllocSysStrin g();
}
catch(...){
return E_OUTOFMEMORY;
}
delete pwStr;
return S_OK;
}

//C#
string s = null;
LargeStringClas s obj = new LargeStringClas s ();
try {
obj.GetLargeStr ing(out s);
...

Willy.
Nov 17 '05 #6
Thanks a lot! that worked. The way I allocated the BSTR in the ActiveX before
was:
STDMETHODIMP CNoReg::GetLarg eString(BSTR* large)
{
std::string str;
// making Str bigger than 50,000...

*large= _bstr_t(str.c_s tr());
return S_OK;
}

Can you tell me what's the difference between that and using CAtlString?

Thanks,
Gilad Walden.
"Willy Denoyette [MVP]" wrote:

"Gilad Walden" <Gi*********@di scussions.micro soft.com> wrote in message
news:74******** *************** ***********@mic rosoft.com...
I have tested it with an Un-managed client (MFC) and exactly the same
string
that crashes .Net works fine in the MFC client.

Maybe you should post your code, anyway, this works for me...

//C++

STDMETHODIMP CNoReg::GetLarg eString(BSTR* large){
const int buffSize = 65000;
wchar_t* pwStr = new wchar_t[buffSize];
wmemset(pwStr, 0, buffSize);
// Fill with all 'A', leave room for null char.
for (int i = 0;i < buffSize-1; i++)
pwStr[i] = L'A';
try {
CAtlString s(pwStr);
*large = s.AllocSysStrin g();
}
catch(...){
return E_OUTOFMEMORY;
}
delete pwStr;
return S_OK;
}

//C#
string s = null;
LargeStringClas s obj = new LargeStringClas s ();
try {
obj.GetLargeStr ing(out s);
...

Willy.

Nov 17 '05 #7
The difference is that your version contains a bug, you should never return
a BSTR by reference from a _bstr_t wrapper without copying/detaching the
wrapped BSTR first. The _bstr_t wrapper manages it's own lifecycle, so
basically what you are doing is:
- Construction of a _bstr_t object
- Conversion of your str to a BSTR
- Assignment of the BSTR to large
- Destruction of the BSTR
so what you return a pointer to a destructed object hence the undefined
behavior.

What you need to do when using the CRT _bstr_t wrapper (or any other COM
wrapper class like CComBSTR) is:
// return the detached underlying BSTR from the wrapper
*large= _bstr_t(str.c_s tr()).Detach();
// return a copy of the underlying BSTR
or copy the wrapped BSTR first like..
*large= _bstr_t(str.c_s tr()).Copy();

In both cases ownership of the BSTR is transfered to the caller, so it's up
to the caller to free the BSTR., this is done automatically by the COM
interop layer in the CLR.

Willy.

"Gilad Walden" <Gi*********@di scussions.micro soft.com> wrote in message
news:58******** *************** ***********@mic rosoft.com...
Thanks a lot! that worked. The way I allocated the BSTR in the ActiveX
before
was:
STDMETHODIMP CNoReg::GetLarg eString(BSTR* large)
{
std::string str;
// making Str bigger than 50,000...

*large= _bstr_t(str.c_s tr());
return S_OK;
}

Can you tell me what's the difference between that and using CAtlString?

Thanks,
Gilad Walden.
"Willy Denoyette [MVP]" wrote:

"Gilad Walden" <Gi*********@di scussions.micro soft.com> wrote in message
news:74******** *************** ***********@mic rosoft.com...
>I have tested it with an Un-managed client (MFC) and exactly the same
>string
> that crashes .Net works fine in the MFC client.
>

Maybe you should post your code, anyway, this works for me...

//C++

STDMETHODIMP CNoReg::GetLarg eString(BSTR* large){
const int buffSize = 65000;
wchar_t* pwStr = new wchar_t[buffSize];
wmemset(pwStr, 0, buffSize);
// Fill with all 'A', leave room for null char.
for (int i = 0;i < buffSize-1; i++)
pwStr[i] = L'A';
try {
CAtlString s(pwStr);
*large = s.AllocSysStrin g();
}
catch(...){
return E_OUTOFMEMORY;
}
delete pwStr;
return S_OK;
}

//C#
string s = null;
LargeStringClas s obj = new LargeStringClas s ();
try {
obj.GetLargeStr ing(out s);
...

Willy.

Nov 17 '05 #8

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

Similar topics

1
2086
by: Gabby Shainer | last post by:
Hello, I've written an ATL web server that implements a HelloDCOM method which then calls a DCOM EXE server only to return the bstrInput prefixed by a "Hello " string. When calling the DCOM interface, I get an E_ACCESSDENIED (0x80070005) error code in return. What am I doing wrong? my WebService method code:
7
1987
by: Aris | last post by:
Hi all! this is the code: #include <iostream.h> #include <stdlib.h> #include <stdio.h> #include <string.h> void MyFunction(char *B) { cout<<sizeof(B)<<endl; //(1)
37
5481
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 32 bytes, because of the fact that a pointer, is 8 bytes instead of 4 bytes. The length prefix -still- is a UINT however and not a UINT_PTR.
0
1245
by: Jason Chrin | last post by:
Hello. I've been trying to use a 3rd party API within a console application. The program runs fine, but when it exits, I get a Memory cannot be read error. I've searched for the past few days, but I can't seem to find the solution. Any help or a point in the right direction is greatly appreciated. My test code is as follows: using System; using System.Runtime.InteropServices; namespace IOTest
1
4195
by: Jason | last post by:
Hi, I have a problem with some C# code. I have a function in a c++ dll which returns a BSTR. I have retrieved the BSTR using p/invoke but the data returned contains what appears to be random data at the start of the string followed by correct data. I am wondering whether it is the length of the BSTR prepended to the string that I am picking up, but doesn't SysAllocStringByteLen get rid of this? to retrieve the data:
0
1382
by: Rob C | last post by:
I have several methods implemented in a webservice written in C#. The methods execute SQL against a SQL Server 2005 db and returns a Dataset (as XML). I am utilizing the webservice from a VC++ app by adding the web ref to the project which creates the header file for making the calls. I traced through the method call in my app and found the problem in the CAtlHttpClientT<TSocketClasstemplate implementation. The problem is happening in...
0
1331
by: SantaClaus | last post by:
Hi all, I'm using a BSTR as an out parameter in a function which reads a file. Here is my code. HRESULT __stdcall CA::getFile(BSTR bstr,BSTR *fileCont) { if (!fileCont) return E_POINTER; wstring str; char sz_path;
2
1484
by: Newsgroups | last post by:
Hi, I found some code from codeproject site using WMI in VC++. I have created a method having the following code in it. It works fine when I am running into "Admin" accound in Windows XP Pro while in "Restricted user account", its not able to run. It's giving error messsage "Could not enumerate" so it seems "pEnumObject" seems null or empty. Please help, Thanks in advance,
0
2419
by: sandeepkavade | last post by:
hi all, i am having a sdk with fires an event. i am trying to catch that event in other C++ console application, i have derived my CEventSink class from IDispEventImpl EventSink.h: #pragma once #include <atlbase.h>
0
9596
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,...
0
10364
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 tapestry of website design and digital marketing. It's not merely about having a website; it's about crafting an immersive digital experience that captivates audiences and drives business growth. The Art of Business Website Design Your website is...
1
10370
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
10109
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 protocol has its own unique characteristics and advantages, but as a user who is planning to build a smart home system, I am a bit confused by the choice of these technologies. I'm particularly interested in Zigbee because I've heard it does some...
0
9186
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
7649
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
6876
by: conductexam | last post by:
I have .net C# application in which I am extracting data from word file and save it in database particularly. To store word all data as it is I am converting the whole word file firstly in HTML and then checking html paragraph one by one. At the time of converting from word file to html my equations which are in the word document file was convert into image. Globals.ThisAddIn.Application.ActiveDocument.Select();...
0
5678
by: adsilva | last post by:
A Windows Forms form does not have the event Unload, like VB6. What one acts like?
1
4328
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

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.