Subject | TIB_Connection in a DLL, Access Violation (I hv read the Archive Posts) |
---|---|
Author | R. S. Patil |
Post date | 2005-03-25T13:53:43Z |
Dear Friends,
I use D5->IBO 4.2 Hg-> FB 1.5.2
I have searched through archives and have read
most interesting post in past. Depending on that
I have created a Test Main Exe and a Test DLL form
#################################################################
Jason has given Following Point in his FAQ
When trying to share a connection DON'T try to share the
reference to the IB_Connection component. Give every DLL
its own TIB_Connection and simply share the connection
handle between them. Use the dbHandle property and assign the
value from it to the dbHandleShared property of the
TIB_Connection components in the DLL instances. Use whatever
means you want to pass the value, since it is just a simple
integer.
One vital point: close the TIB_Connection in the EXE before you
terminate or destroy the DLL calls. Releasing the DLL resources
before you close the TIB_Connection can cause some messy problems
at termination!
(Jason Wharton)
#################################################################
Each form in a dll is designed to be independent
with a TIB_Connection and all queries/SP/Script/Txn
component pointing to that. all queries get closed in
form close event. Rest of the form is same as
it was in traditional all in one exe application.
The application works fine on XP but on 98 sometimes
numerous AV error are shown I dont Know why.
This happens sometime while the DLL form closes or
sometimes when Main Form closes.
I am linking this to "One Vital Point" Jason has mentioned.
I am not closing IB_Connection in main exe since at a given
time user might have opened n forms in the application and
can close one of them. Since I am releasing DLL as soon as
a form in that dll has been closed. If i close and reopen
IB_Connection in main form then remaining forms which are open
will be redundant with empty queries.
I think somebody already faced this type of situation
Can somebody Shed some light on this.
Thanks and Best Regards
R. S. Patil
The mechanism i have designed is as follows.
The total exe->dll mechanism is as given below
// dll Form file --------------------------------
Function DLLForm(menHnd, libHnd, apphnd, dbHnd : THandle) : Boolean;
stdcall; export;
begin
Application.Handle := apphnd;
frmSomeForm := TfrmSomeForm.Create(Application);
with frmSomeForm do
begin
{Main_Hndl, lib_Hndl - Variables Declared in Private section of form}
lib_Hndl := libHnd; // Dll Handle
Main_Hndl := menHnd; // Main Form Handle
{
IB_Connection_DLL is TIB_Connection put on every Form and all
queries/Transactions pointing to this at Design Time
}
IB_Connection_DLL.dbHandleShared := dbHnd;
Show; // or Show Modal
end;
end;
procedure TfrmSomeForm.FormShow;
begin
OpenQueries
end;
procedure TfrmSomeForm.FormClose(Sender: TObject;
var Action: TCloseAction);
begin
Close All Queries
RollBack all Transactions
Close All Transactions
IB_Connection_DLL.dbHandleShared := nil;
Action := caFree;
end;
procedure TfrmSomeForm.FormDestroy(Sender: TObject);
var
msg : TMessage;
begin
msg.WParam := self.lib_Hndl div MAXLONGINT;
msg.LParam := self.lib_Hndl MOD MAXLONGINT;
PostMessage(Main_Hndl,CM_FREE_LIB, msg.WParam, msg.LParam);
end;
//============================================================
//============================================================
// Main Exe Form file ---------------------------
{This is common function Calling DLL Form Proc}
function DLLFormShow(DLLNAME : string; Formfunction : string; menHnd,
appHnd, dbHnd : THandle) : boolean;
var
hnd : THandle;
DLLForm : TDLLForm;
begin
Result := false;
hnd := LoadLibrary(PCHAR(DLLNAME));
If hnd = 0 Then
begin
MessageDlg('Error in loading Application DLL file.'#10+
'File Path : '+DLLNAME,mtError,[mbOk],0);
Exit;
END;
DLLForm := GetProcAddress(hnd,PCHAR(Formfunction));
If @DLLForm <> Nil Then
Result := DLLForm(menHnd, hnd, apphnd, dbHnd)
else
MessageDlg(Formfunction+' is Not Part Of '+DLLNAME,mtError,[mbOk],0);
end;
//----------------------------------------------------------------
procedure TfrmMainExeForm.CM_FREE_LIB_Proc(var Message: TMessage);
var
DLLName : array[0..MAX_PATH] of char;
DllFileName : String;
hnd : THandle;
begin
hnd := Message.WParam * MAXLONGINT + Message.LParam;
FillChar(DLLName, sizeof(DLLName), #0);
GetModuleFileName(hnd, DLLName, sizeof(DLLName));
DllFileName := ExtractFileName(String(DLLName));
try
FreeLibrary(hnd);
except
showMessage('FreeLibrary Exception ' + DllFileName + ' Hnd ' +
IntToStr(hnd));
end;
end;
//------------------------------------------------------------------
I use D5->IBO 4.2 Hg-> FB 1.5.2
I have searched through archives and have read
most interesting post in past. Depending on that
I have created a Test Main Exe and a Test DLL form
#################################################################
Jason has given Following Point in his FAQ
When trying to share a connection DON'T try to share the
reference to the IB_Connection component. Give every DLL
its own TIB_Connection and simply share the connection
handle between them. Use the dbHandle property and assign the
value from it to the dbHandleShared property of the
TIB_Connection components in the DLL instances. Use whatever
means you want to pass the value, since it is just a simple
integer.
One vital point: close the TIB_Connection in the EXE before you
terminate or destroy the DLL calls. Releasing the DLL resources
before you close the TIB_Connection can cause some messy problems
at termination!
(Jason Wharton)
#################################################################
Each form in a dll is designed to be independent
with a TIB_Connection and all queries/SP/Script/Txn
component pointing to that. all queries get closed in
form close event. Rest of the form is same as
it was in traditional all in one exe application.
The application works fine on XP but on 98 sometimes
numerous AV error are shown I dont Know why.
This happens sometime while the DLL form closes or
sometimes when Main Form closes.
I am linking this to "One Vital Point" Jason has mentioned.
I am not closing IB_Connection in main exe since at a given
time user might have opened n forms in the application and
can close one of them. Since I am releasing DLL as soon as
a form in that dll has been closed. If i close and reopen
IB_Connection in main form then remaining forms which are open
will be redundant with empty queries.
I think somebody already faced this type of situation
Can somebody Shed some light on this.
Thanks and Best Regards
R. S. Patil
The mechanism i have designed is as follows.
The total exe->dll mechanism is as given below
// dll Form file --------------------------------
Function DLLForm(menHnd, libHnd, apphnd, dbHnd : THandle) : Boolean;
stdcall; export;
begin
Application.Handle := apphnd;
frmSomeForm := TfrmSomeForm.Create(Application);
with frmSomeForm do
begin
{Main_Hndl, lib_Hndl - Variables Declared in Private section of form}
lib_Hndl := libHnd; // Dll Handle
Main_Hndl := menHnd; // Main Form Handle
{
IB_Connection_DLL is TIB_Connection put on every Form and all
queries/Transactions pointing to this at Design Time
}
IB_Connection_DLL.dbHandleShared := dbHnd;
Show; // or Show Modal
end;
end;
procedure TfrmSomeForm.FormShow;
begin
OpenQueries
end;
procedure TfrmSomeForm.FormClose(Sender: TObject;
var Action: TCloseAction);
begin
Close All Queries
RollBack all Transactions
Close All Transactions
IB_Connection_DLL.dbHandleShared := nil;
Action := caFree;
end;
procedure TfrmSomeForm.FormDestroy(Sender: TObject);
var
msg : TMessage;
begin
msg.WParam := self.lib_Hndl div MAXLONGINT;
msg.LParam := self.lib_Hndl MOD MAXLONGINT;
PostMessage(Main_Hndl,CM_FREE_LIB, msg.WParam, msg.LParam);
end;
//============================================================
//============================================================
// Main Exe Form file ---------------------------
{This is common function Calling DLL Form Proc}
function DLLFormShow(DLLNAME : string; Formfunction : string; menHnd,
appHnd, dbHnd : THandle) : boolean;
var
hnd : THandle;
DLLForm : TDLLForm;
begin
Result := false;
hnd := LoadLibrary(PCHAR(DLLNAME));
If hnd = 0 Then
begin
MessageDlg('Error in loading Application DLL file.'#10+
'File Path : '+DLLNAME,mtError,[mbOk],0);
Exit;
END;
DLLForm := GetProcAddress(hnd,PCHAR(Formfunction));
If @DLLForm <> Nil Then
Result := DLLForm(menHnd, hnd, apphnd, dbHnd)
else
MessageDlg(Formfunction+' is Not Part Of '+DLLNAME,mtError,[mbOk],0);
end;
//----------------------------------------------------------------
procedure TfrmMainExeForm.CM_FREE_LIB_Proc(var Message: TMessage);
var
DLLName : array[0..MAX_PATH] of char;
DllFileName : String;
hnd : THandle;
begin
hnd := Message.WParam * MAXLONGINT + Message.LParam;
FillChar(DLLName, sizeof(DLLName), #0);
GetModuleFileName(hnd, DLLName, sizeof(DLLName));
DllFileName := ExtractFileName(String(DLLName));
try
FreeLibrary(hnd);
except
showMessage('FreeLibrary Exception ' + DllFileName + ' Hnd ' +
IntToStr(hnd));
end;
end;
//------------------------------------------------------------------