bozo7
asked on
DLL Connection ?
Using D5, All update applied, ADO, SQL 2000.
I have an application with a very large complex report in a DLL. I open the dll and run the report just fine. Then close dll just fine. Show Main form and get an access violation.
I tried disconnecting the current ADO connection, then opening the DLL, run report, close dll, then open main connection again. No access violation.
I don't want to open the tables again. It is about a 10 - 15 second delay.
Is there a way that I can tell the DLL ado objects to use the ADOConnection of the main application?
I tried using a connection string int the DLL instead of an ADOConnection but got the access violoation.
Thanks,
Ross
I have an application with a very large complex report in a DLL. I open the dll and run the report just fine. Then close dll just fine. Show Main form and get an access violation.
I tried disconnecting the current ADO connection, then opening the DLL, run report, close dll, then open main connection again. No access violation.
I don't want to open the tables again. It is about a 10 - 15 second delay.
Is there a way that I can tell the DLL ado objects to use the ADOConnection of the main application?
I tried using a connection string int the DLL instead of an ADOConnection but got the access violoation.
Thanks,
Ross
Pass the connection object(Pointer) to the DLL
ASKER
How?
And at design time I leave the connection property blank right? and then at runtime how do I tell the ADO object to use the connection object?
Ross
And at design time I leave the connection property blank right? and then at runtime how do I tell the ADO object to use the connection object?
Ross
You don't have to leave it blank but on the create of the form or datamodule that holds the ADO connection object you can assign a connection string then pass the in your dll you pass the connection object you created to it. Or you can pass the connection string as a PChar and to the Dll.
ASKER
I don't think that passing the connection string will work. I used a udl file and had the objects in the dll use the same udl as the connection object in the calling app. Still generated the error.
How do I pass the connection object to the dll? I tried passing it as a TADOConnection parameter, that did not work.
Ross
How do I pass the connection object to the dll? I tried passing it as a TADOConnection parameter, that did not work.
Ross
Make the dll an comserver that way you would be able to pass the connection object
ASKER
I don't mean to sound stupid but I don't know how to make a DLL a comserver.
Thanks for your help.
Ross
Thanks for your help.
Ross
ASKER
I will give this another try
This is my test dll. I am attempting to pass the ado connection to the dll. It works fine in the dll it runs the query. But when it returns to the calling application it returns a access violation. The code for the calling application is below. You will notice that in that code there is a try except the except portion is not called.
library testing;
uses
SysUtils,
Classes,
adodb,
dialogs;
procedure AdminReport(DB : TADOConnection);
var Q : TADOQuery;
begin
Q := TADOQuery.create(nil);
try
with q do
begin
Connection := DB;
sql.add('select count(*) S from cells');
open;
if fieldbyname('s').value > 0 then
showmessage('Ha')
else
showmessage('crap');
end;
finally
freeandnil(Q);
end;
end;
Exports
AdminReport;
end.
Calling Application procedure
procedure TfrmMain.mniAdmitClick(Sen der: TObject);
var
LibHandle : THandle;
AdminReport : TAdminReport;
begin
frmMain.hide;
LibHandle := LoadLibrary('C:\Projects\O utcomes\Te sting\test ing.dll';
try
try
if LibHandle = 0 then
raise EDLLLoadError.Create('Unab le to Load Admin Report');
@AdminReport := GetProcAddress(LibHandle, 'AdminReport');
if not (@AdminReport = nil) then
AdminReport(dtmMain.adoMai n)
else
RaiseLastWin32Error;
finally
FreeLibrary(LibHandle); // Unload the DLL.
end;
except
showmessage('Help');
raise;
end;
end;//After this end I get an access violation!!!
Thank You
Ross
This is my test dll. I am attempting to pass the ado connection to the dll. It works fine in the dll it runs the query. But when it returns to the calling application it returns a access violation. The code for the calling application is below. You will notice that in that code there is a try except the except portion is not called.
library testing;
uses
SysUtils,
Classes,
adodb,
dialogs;
procedure AdminReport(DB : TADOConnection);
var Q : TADOQuery;
begin
Q := TADOQuery.create(nil);
try
with q do
begin
Connection := DB;
sql.add('select count(*) S from cells');
open;
if fieldbyname('s').value > 0 then
showmessage('Ha')
else
showmessage('crap');
end;
finally
freeandnil(Q);
end;
end;
Exports
AdminReport;
end.
Calling Application procedure
procedure TfrmMain.mniAdmitClick(Sen
var
LibHandle : THandle;
AdminReport : TAdminReport;
begin
frmMain.hide;
LibHandle := LoadLibrary('C:\Projects\O
try
try
if LibHandle = 0 then
raise EDLLLoadError.Create('Unab
@AdminReport := GetProcAddress(LibHandle, 'AdminReport');
if not (@AdminReport = nil) then
AdminReport(dtmMain.adoMai
else
RaiseLastWin32Error;
finally
FreeLibrary(LibHandle); // Unload the DLL.
end;
except
showmessage('Help');
raise;
end;
end;//After this end I get an access violation!!!
Thank You
Ross
ASKER
I changed the parameter DB to a var parameter so the DLL procedure now looks like
procedure AdminReport(var DB : TADOConnection);
procedure AdminReport(var DB : TADOConnection);
Try running outside the delphi enviroment and see what happens
ASKER
Same thing. I get the 'Ha' message like I should. Then a quick flash of the main form and nothing.
When I ran your could I got a Win 32 API Error
ASKER
I figured it out!
The AdminReport variable I had delclared like so
TAdminReport = procedure (AHandle: THandle; var DB: TADOConnection); stdcall;
it should have been like this
TAdminReport = procedure (AHandle: THandle; var DB: TADOConnection);
The 'stdcall' made the difference. So I am not sure what to do with points for this question.
Thanks,
Ross
The AdminReport variable I had delclared like so
TAdminReport = procedure (AHandle: THandle; var DB: TADOConnection); stdcall;
it should have been like this
TAdminReport = procedure (AHandle: THandle; var DB: TADOConnection);
The 'stdcall' made the difference. So I am not sure what to do with points for this question.
Thanks,
Ross
Keep them if you want not a big deal
ASKER
I will reduce points to 75 and give you the answer for helping me.
Is that ok?
Is that ok?
ASKER CERTIFIED SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.