473,387 Members | 1,542 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,387 software developers and data experts.

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 7057
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*********@discussions.microsoft.com> wrote in message
news:44**********************************@microsof t.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*********@discussions.microsoft.com> wrote in message
news:44**********************************@microsof t.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*********@discussions.microsoft.com> wrote in message
news:44**********************************@microsof t.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*********@discussions.microsoft.com> wrote in message
news:44**********************************@microsof t.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*********@discussions.microsoft.com> wrote in message
news:74**********************************@microsof t.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::GetLargeString(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.AllocSysString();
}
catch(...){
return E_OUTOFMEMORY;
}
delete pwStr;
return S_OK;
}

//C#
string s = null;
LargeStringClass obj = new LargeStringClass ();
try {
obj.GetLargeString(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::GetLargeString(BSTR* large)
{
std::string str;
// making Str bigger than 50,000...

*large= _bstr_t(str.c_str());
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*********@discussions.microsoft.com> wrote in message
news:74**********************************@microsof t.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::GetLargeString(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.AllocSysString();
}
catch(...){
return E_OUTOFMEMORY;
}
delete pwStr;
return S_OK;
}

//C#
string s = null;
LargeStringClass obj = new LargeStringClass ();
try {
obj.GetLargeString(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_str()).Detach();
// return a copy of the underlying BSTR
or copy the wrapped BSTR first like..
*large= _bstr_t(str.c_str()).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*********@discussions.microsoft.com> wrote in message
news:58**********************************@microsof t.com...
Thanks a lot! that worked. The way I allocated the BSTR in the ActiveX
before
was:
STDMETHODIMP CNoReg::GetLargeString(BSTR* large)
{
std::string str;
// making Str bigger than 50,000...

*large= _bstr_t(str.c_str());
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*********@discussions.microsoft.com> wrote in message
news:74**********************************@microsof t.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::GetLargeString(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.AllocSysString();
}
catch(...){
return E_OUTOFMEMORY;
}
delete pwStr;
return S_OK;
}

//C#
string s = null;
LargeStringClass obj = new LargeStringClass ();
try {
obj.GetLargeString(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
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...
7
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
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...
0
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,...
1
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...
0
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++...
0
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;...
2
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...
0
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...
0
by: taylorcarr | last post by:
A Canon printer is a smart device known for being advanced, efficient, and reliable. It is designed for home, office, and hybrid workspace use and can also be used for a variety of purposes. However,...
0
by: Charles Arthur | last post by:
How do i turn on java script on a villaon, callus and itel keypad mobile phone
0
by: ryjfgjl | last post by:
If we have dozens or hundreds of excel to import into the database, if we use the excel import function provided by database editors such as navicat, it will be extremely tedious and time-consuming...
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...
0
by: Hystou | last post by:
There are some requirements for setting up RAID: 1. The motherboard and BIOS support RAID configuration. 2. The motherboard has 2 or more available SATA protocol SSD/HDD slots (including MSATA, M.2...
0
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,...
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,...

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.