A problem I recently encountered is following.
I've a .DLL written in Delphi this DLL has a function Divide (which accepts two integers as parameter) and returns its value as it should.
function Divide( aFirstValue, aSecondValue : Integer ) : Double; stdcall;
begin
result := aFirstValue / aSecondValue;
end;
Now if I use the following parameters '5, 0' then it throws a DivideByZeroException (which is correct :))
But when I call the same .DLL from C# it doesn't catch any exception at all.
[DllImport("DelphiDLL.DLL", EntryPoint = "Divide", SetLastError = true, CharSet = CharSet.Auto, ExactSpelling = true,
CallingConvention = CallingConvention.StdCall)]
public static extern float Divide(Int32 a, Int32 b);
private void Button_Click_2(object sender, System.EventArgs e)
{
try
{
TB.Text += "Divide(a,b) = ";
float temp;
temp = Divide(Convert.ToInt32(aTB.Text), Convert.ToInt32(bTB.Text));
Console.WriteLine(Marshal.GetLastWin32Error());
TB.Text += Convert.ToString(temp) + "\r\n";
}
catch (DivideByZeroException eMsg)
{
}
}
You cannot hope to catch that exception outside the DLL. One of the rules of this form of binary interop is that exceptions cannot be thrown across module boundaries.
The solution is to fix the DLL. Catch the exception in the DLL and return an error code to indicate failure. Indeed you should protect all entry points against throwing an exception. Don't just catch zero divide exceptions, catch them all and convert them into error code return values.
function CalcQuotient(a, b: Integer; out quotient: Double): Integer; stdcall;
begin
try
quotient := a / b;
Result := 0;// you'd use a constant with a sensible name rather than a magic value
except
on E: Exception do begin
Result := GetErrorCode(E);
// where GetErrorCode is your function that converts exceptions into error codes
end;
end;
end;
Some asides regarding your p/invoke usage:
CharSet
when none of the arguments contains text.SetLastError = true
is incorrect and should be removed. The function doesn't call SetLastError
. Consequently the call to Marshal.GetLastWin32Error()
is erroneous and should be removed.If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With