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.

Wednesday, September 06, 2006

 

Cross compiler Data Access


Object Pascal compilers offers a wide range of classes and components that allows you to connect to different databases, ranging from BDE to open source components. But many of them only works in Delphi or only in FreePascal, turning very dificult to develop cross platform database applications.

One of the most known data access components is Zeos Lib, a heavy weight component library that allows you to acces a lot of database backends like MySql, PostGreSQL, Oracle, MsSql Server, Interbase and others. It's free, open source and works on Delphi, Kylix and FreePascal. You can get more information and download from http://sourceforge.net/projects/zeoslib, also, if you want to install it in Lazarus must read this http://wiki.lazarus.freepascal.org/index.php/Zeos_tutorial.

If you (like me) like smaller and faster programs, i'll recommend a small library called LibSQL. Just like Zeos, this library allows access to different databases, but allows you to use driver you want, making the executable many times smaller than Zeos. If you want to download it, go to http://sourceforge.net/projects/libsql

If you know different cross platform libraries or components like Zeos or LibSQL, please comment on them.

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