Wednesday, September 20, 2006

 

Why i can't capture exceptions from Dlls?


A very common topic in newsgroups is Dll Exception handling. If your dll raises an exception, the exception handler in the host app should not be able to recognize the class of the exception it trapped. That's because the host application doesn't recognizes the exception class raised by the dll.

The recommended aproach is to capture any exception within the Dll and create functions that return values of success or failure, then the host application can evaluate such results and raise an exception.

This is an example produces different results when compiled with Delphi or FreePascal, you shouldn't do this:

library failedlib;

uses
SysUtils;


function divide(a, b: integer): Boolean; cdecl;
begin
if b = 0 then
raise Exception.Create('Can''t divide by zero');
Result := True;

end;

exports
divide;

end.

program sample;

{$APPTYPE CONSOLE}

type
TDivide = function (a, b: integer): Boolean; cdecl;


var
FuncDivide: TDivide;
lHandle: Cardinal;

begin
lHandle := LoadLibrary('failedlib.dll');
if lHanlde <> 0 then

begin
FuncDivide = GetProcAddress(lHandle, 'divide');
if pointer(@FuncDivide) <> nil then
begin

try
if FuncDivide(10, 0) then
writeln('Success!');
except

writeln('Failure!');
end;
end;
UnloadLibrary(lHandle);
end;
end.


The correct method is this:

library correctlib;

uses
SysUtils;


function divide(a, b: integer): Boolean; cdecl;
var
c: Integer;
begin
(* Catch any exception before return *)
try

c := a div b;
Result := True;
except
Result := False;
end;
end;

exports
divide;


end.

program sample;

{$APPTYPE CONSOLE}

type
TDivide = function (a, b: integer): Boolean; cdecl;


var
FuncDivide: TDivide;
lHandle: Cardinal;

begin
lHandle := LoadLibrary('correctlib.dll');
if lHanlde <> 0 then

begin
FuncDivide = GetProcAddress(lHandle, 'divide');
if pointer(@FuncDivide) <> nil then
begin

if FuncDivide(10, 0) then
writeln('Success!')
else
(* The exception is raised in the host app, not in the DLL *)

raise 'Failure!';
end;
UnloadLibrary(lHandle);
end;
end.

Comments:
Hello Leonardo - yes many people have confused PSP with ASP or JSP emulation because "Server Pages" sounds as if they are pages you store on the server. Really they are binary server programs (BSP?). I tried to change the name of PSP over to "Pascal Web Utilities" but the acronym "PWU" is harder to pronounce in conversation than "PSP".

We can always find something more descriptive for the PSP project to encourage more people to research it. What do you think is a good acronym? I guess we should consider that BSP is a bit binary oriented and might turn some people off. I figured some acronym with "Web Utilities" or "Internet Utilities" would be nice.

Thank you for mentioning PSP in your blog!

L505
 
Post a Comment



<< Home

This page is powered by Blogger. Isn't yours?