Interop - string from dll issue

J

Jason

I am trying to retrieve string data from a c++ dll:

extern "C" __declspec( dllexport ) const char * getbagstr();
extern "C" __declspec( dllexport ) const char * getbagstr() {
const char * buff = g.getbag()->getbagstr(true).c_str();
return buff;
}

VS 2005, C# declaration

[DllImport("Hotspots",EntryPoint="getbagstr",
CallingConvention=CallingConvention.StdCall)]
private static extern string getbagstr();


console output after calling function in C# is:

v►☺YYYYYYYYYYYYYZZZZZZZZZ

Where are the extra characters coming from at the beginning? I have tried
returning a BSTR but I had the same result. The data is correct, but only
after the junk at the beginning.

Any ideas on how to avoid this problem?

Thanks.
 
I

Ignacio Machin \( .NET/ C# MVP \)

Hi,

Are you sure that g.getbag()->getbagstr(true).c_str(); is working correctly
and not inserting it?
 
J

Jason

Hi,

Are you sure that g.getbag()->getbagstr(true).c_str(); is working correctly
and not inserting it?


--

Yes, I am very confident about this, I have retested in VC++ 6.0 with the
same interfaces and everythign works fine. Only calling function through
c# interop causes this problem.
 
B

Ben Voigt

This is one possibility...

Jason said:
I am trying to retrieve string data from a c++ dll:

extern "C" __declspec( dllexport ) const char * getbagstr();
extern "C": defaults to __cdecl, I think.
[DllImport("Hotspots",EntryPoint="getbagstr",
CallingConvention=CallingConvention.StdCall)]
But here is __stdcall.


In any case, you should not rely on the default, you should explicitly tag
the calling convention with the appropriate keyword in both C++ and C#.
 
J

Jason

This is one possibility...

Jason said:
I am trying to retrieve string data from a c++ dll:

extern "C" __declspec( dllexport ) const char * getbagstr();
extern "C": defaults to __cdecl, I think.
[DllImport("Hotspots",EntryPoint="getbagstr",
CallingConvention=CallingConvention.StdCall)]
But here is __stdcall.


In any case, you should not rely on the default, you should explicitly tag
the calling convention with the appropriate keyword in both C++ and C#.

Tried __stdcall and __cdecl and neither made any difference. There is a
problem with declaring the function in the dll, take a look at this

extern "C" __declspec( dllexport ) char * getbagstr();
extern "C" __declspec( dllexport ) char * getbagstr() {
const char * buff = g.getbag()->getbagstr(true).c_str();
char * c = const_cast<char*>(buff);
return c;
}

I cannot prefix char * with the calling convention as it will not compile.
I have tried declaring it as const char * as well, the latest version above
is just another attempt. I have tried specifiying all possible calling
conventions from C# whatever the C function defaults to and it still does
not work. This garbage data is really malignant.
 
B

Ben Voigt

Jason said:
This is one possibility...

Jason said:
I am trying to retrieve string data from a c++ dll:

extern "C" __declspec( dllexport ) const char * getbagstr();
extern "C": defaults to __cdecl, I think.
[DllImport("Hotspots",EntryPoint="getbagstr",
CallingConvention=CallingConvention.StdCall)]
But here is __stdcall.


In any case, you should not rely on the default, you should explicitly
tag
the calling convention with the appropriate keyword in both C++ and C#.

Tried __stdcall and __cdecl and neither made any difference. There is a
problem with declaring the function in the dll, take a look at this

extern "C" __declspec( dllexport ) char * getbagstr();
extern "C" __declspec( dllexport ) char * getbagstr() {
const char * buff = g.getbag()->getbagstr(true).c_str();
char * c = const_cast<char*>(buff);
return c;
}

I cannot prefix char * with the calling convention as it will not compile.

You wouldn't prefix char* with the calling convention, it is not the return
type that is modified. Rather it would look like:

extern "C" __declspec( dllexport ) const char * __stdcall getbagstr();

Anyway, don't use const_cast.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top