Calling a C++ DLL from a C# program. Unexpected behaviour

  • Thread starter Thread starter Guest
  • Start date Start date
G

Guest

Hi there!

I’m having a strange problem with a c++ dll that is called from a c#
program. The dll wraps a large piece of c++ software that uses exceptions for
its error-signalling. To keep the exception mechanism away from the c# end,
all functions in the dll are embedded in catch-all blocks that return ‘false’
if anything throws an exception. Using a c++ program as the caller, the dll
can be shown to work and return false on an exception.

Now, the fun part: If I use c# to access the function, it returns ‘true’
every time an exception occurs. If I step into the dll, using the mixed-mode
debugger, the results are pretty interesting. Upon stepping over the line
that will case an exception to be thrown, the debugger jumps back to the c#
code, as if the function returned. It does not enter the exception handler,
like it did with c++ code calling the function.

I get this behaviour with all similar code.

FWIW, the DllImport lines look like this: [DllImport("somedll.dll",
CharSet=CharSet.Ansi)]

I would really appreciate some help, as this is a major showstopper for us.

Thanks in advance,

Ulf
 
Ascaron said:
Now, the fun part: If I use c# to access the function, it returns
'true' every time an exception occurs. If I step into the dll, using
the mixed-mode debugger, the results are pretty interesting. Upon
stepping over the line that will case an exception to be thrown, the
debugger jumps back to the c# code, as if the function returned. It
does not enter the exception handler, like it did with c++ code
calling the function.

Can you give the complete prototype of one of the methods you are
calling?

I suspect that this is a marshalling problem. If I do this:

// C++
extern "C" __declspec(dllexport) bool Test()
{
try
{
throw 1;
}
catch(...)
{ return false;}
return true;
}
// C#
class Tester
{
[DllImport("lib")]
public static extern bool Test();
}

I find that Tester.Test() returns true, whereas, as you say, it should
return false. If I change the C++ to:

extern "C" __declspec(dllexport) BOOL Test()
{
try
{
throw 1;
}
catch(...)
{ return FALSE;}
return TRUE;
}

then Tester.Test() returns false, as it should.

I don't know what is happening here, because if I remove the try/catch
block from Test version with bool (and return false), then it works as
expected.

Richard
 
Hello Richard

Thanks for your reply, this solved the problem perfectly. Still it left us
wondering why ;)

Cheers

Ulf


Richard Grimes said:
Ascaron said:
Now, the fun part: If I use c# to access the function, it returns
'true' every time an exception occurs. If I step into the dll, using
the mixed-mode debugger, the results are pretty interesting. Upon
stepping over the line that will case an exception to be thrown, the
debugger jumps back to the c# code, as if the function returned. It
does not enter the exception handler, like it did with c++ code
calling the function.

Can you give the complete prototype of one of the methods you are
calling?

I suspect that this is a marshalling problem. If I do this:

// C++
extern "C" __declspec(dllexport) bool Test()
{
try
{
throw 1;
}
catch(...)
{ return false;}
return true;
}
// C#
class Tester
{
[DllImport("lib")]
public static extern bool Test();
}

I find that Tester.Test() returns true, whereas, as you say, it should
return false. If I change the C++ to:

extern "C" __declspec(dllexport) BOOL Test()
{
try
{
throw 1;
}
catch(...)
{ return FALSE;}
return TRUE;
}

then Tester.Test() returns false, as it should.

I don't know what is happening here, because if I remove the try/catch
block from Test version with bool (and return false), then it works as
expected.

Richard
 
Back
Top