URGENT: Local variables dissapear after unmanaged function call

  • Thread starter Thread starter Papa.Coen
  • Start date Start date
P

Papa.Coen

Right after I call a function in an external dll, some of my local
variables, not used in the call (!!!) in any way, are 'null' right
after the call.

(Pseudo)code

[Dllimport ...]
public static ... calc(...)

StringBuilder sB = new StringBuilder("hello");
String tmp = "I'm on my own";

calc(ref tmp);
// sB = null here!

What's happening here!?
 
Most probably you are using wrong CallingConvention - see description of
this enumeration in MSDN or SDK.
 
Most probably you are using wrong CallingConvention - see description of
this enumeration in MSDN or SDK.


Right after I call a function in an external dll, some of my local
variables, not used in the call (!!!) in any way, are 'null' right
after the call.
(Pseudo)code

[Dllimport ...]
public static ... calc(...)
StringBuilder sB = new StringBuilder("hello");
String tmp = "I'm on my own";
calc(ref tmp);
// sB = null here!
What's happening here!?

Both Cdecl & StdCall have the same effect.
 
Papa.Coen said:
Correction : the StringBuilder isn't null, but an invalid object
reference.

What exactly do you mean by this? What's the exact behaviour?
 
Papa.Coen said:
Right after I call a function in an external dll, some of my local
variables, not used in the call (!!!) in any way, are 'null' right
after the call.

(Pseudo)code

[Dllimport ...]
public static ... calc(...)

StringBuilder sB = new StringBuilder("hello");
String tmp = "I'm on my own";

calc(ref tmp);
// sB = null here!

What's happening here!?

Looks like a classic buffer overrun. Were you supposed to pass a reference
to a String tracking handle? Probably not. So the function took the space
you gave it, just big enough for a tracking handle, and wrote beyond that.
 
Looks like a classic buffer overrun. Were you supposed to pass a reference
to a String tracking handle? Probably not. So the function took the space
you gave it, just big enough for a tracking handle, and wrote beyond that.

If that's the problem,then what is or might be the solution?
Is it even possible to map a c# string to a c++ std:string?
 
Let me tell a little bit more: the starting point is calling a C++
function from dotNET/C#

callMe(std::string* input, std::string* output, str:string* error)

When I tried using StringBuffer for the input (output & error seem to
work just fine as out IntPtr parameters) I got the above error. I've
tried a 'million' different ways to pass the input parameter to the C+
+ dll, but I just can't get it working!
 
Papa.Coen said:
Let me tell a little bit more: the starting point is calling a C++
function from dotNET/C#

callMe(std::string* input, std::string* output, str:string* error)

When I tried using StringBuffer for the input (output & error seem to
work just fine as out IntPtr parameters) I got the above error. I've
tried a 'million' different ways to pass the input parameter to the C+
+ dll, but I just can't get it working!

P/invoke can't handle C++ objects. Not at all, don't even try.

C++/CLI interop can though, so if you write the bit of code calling the C++
functions in a C++/CLI ref class you can convert the .NET String into a C++
std::string and make the call. The C++/CLI ref class is a real .NET type
which can be used from C#.

Another concern is that you seem to have a C++ DLL with objects as
parameters of exported functions. This is badly broken, since different
compilers provide different definitions of std::string. Do you have the
source code of the C++ function? If so, don't make a separate DLL for it,
compile it and the C++/CLI ref class together into a "mixed-mode" assembly.
 
Back
Top