Subject Re: Using a TIBODatabase inside a DLL
Author danielrail
--- In IBObjects@yahoogroups.com, "fabiano_bonin" <fabiano@p...>
wrote:
> I use a TIBODatabase inside a DLL, and it works the same way as the
> TIBODatabase of the main application. When i create a query inside
> the DLL, it automatically assumes the DLL TIBODatabase as it's
> database.
>
> The way i do this is passing the main TIBODatabase to the DLL as
the
> parameter of a procedure, and, inside this procedure:
>
> DLLIBODatabase.SchemaCacheDir := MainIBODatabase.SchemaCacheDir;
> DLLIBODatabase.dbHandleShared := MainIBODatabase.dbHandle;
> DLLIBODatabase.IB_Session.DefaultConnection := DLLIBODatabase;
>
> It's working without problems, and my employee who did this found
> this information asking in this newsgroup. Unfortunatelly i'm not
> having success to search the archives.
>
> Recently Helen told me it's not the right way to do this. Could you
> point me the right way?

Actually it is the right way. The above example is what Jason
mentioned quite awhile back(maybe 3-4 years ago).

Here's what I do in the DLL:

type
pIB_Session = ^TIB_Session;

procedure OpenRecalls(AHandle: THandle;
vIB_Session: pIB_Session);stdcall;
var
OldHandle: THandle;
begin
{Save the DLL handle}
OldHandle := Application.Handle;
{assign the main application's handle to DLL's handle}
Application.Handle := AHandle;
RecallFRM := TRecallFRM.Create(Application);
try
RecallFRM.IB_RecallConnection.dbHandleShared :=
vIB_Session^.DefaultConnection.dbHandle;
RecallFRM.IB_RecallConnection.Connect;
RecallFRM.ShowModal;
finally
RecallFRM.Release;
RecallFRM := nil;
{restore the original DLL handle, otherwise the application will
close}
Application.Handle := OldHandle;
end;
end;

And, in the main application:

type
TOpenRecalls = procedure(AHandle: THandle;
vIB_Session: pIB_Session); stdcall;

var
LibHandle: THandle;
OpenRecalls: TOpenRecalls;
begin
LibHandle := LoadLibrary(pchar(ExtractFilePath(Application.Exename)
+'Your.dll'));
try
if LibHandle=0 then
raise EDLLLoadError.Create('Your.dll was not found.');
@OpenRecalls := GetProcAddress(LibHandle, 'OpenRecalls');
if not (@OpenRecalls=nil) then
OpenRecalls(Application.Handle, @..._MainSession)
else
RaiseLastWin32Error
finally
FreeLibrary(LibHandle)
end
end

You don't have to call the disconnect method for the connection in the
DLL. And, another tip is to change the application handle of the DLL
to point to the main's application handle, but don't forget to
reassign the old DLL handle back to the DLL's application handle(it's
in the above code).

This works for me for the past 3 years.

--
Best regards,
Daniel Rail
Senior System Engineer
ACCRA Group Inc. (www.accra.ca)
ACCRA Med Software Inc. (www.filopto.com)