在动态连接库中做数据查询,关闭出错,急急急 ! (200分)

D

Dbjam

Unregistered / Unconfirmed
GUEST, unregistred user!
我写了一个dll,在dll中要操作数据库,有一exe文件调用这个dll,exe文件退出时内存出错。
程序如下.

//--------------------------------------------- dll
library trans;

uses
SysUtils,
Classes,
windows,
DbTables;

function InitDB(Driver,Service,Database,UserName,Password:pChar;Check:Boolean):Bool;Stdcall;
var
__db:tdatabase;
begin
result:=false;
__db:= TDatabase.Create(nil);
__db.DatabaseName := 'TransTest';
__db.DriverName := Driver;
__db.params.clear;
__db.Params.Add('server name='+Service);
__db.Params.Add('database name='+Database);
__db.Params.Add('user name='+Username);
__db.Params.Add('password='+password);
__db.LoginPrompt := false;
try
__db.Open; // / 如果注释掉这两行,主程序退出不会出错
__db.close; // /
result:=true;
except
end;
__db.free;
end;
end;

exports
InitDB index 2;
{$R *.RES}
begin

end.

//------------------------------------------ exe
unit Unit1;

interface

uses
Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
StdCtrls;
type
TForm1 = class(TForm)
Button1: TButton;
procedure Button1Click(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;
function InitDB(Driver,
Service,
Database,
UserName,
Password:pChar;
Check:Boolean
):Bool;Stdcall;external 'dbtest.dll';
var
Form1: TForm1;

implementation
uses
registry,
DbTables;

{$R *.DFM}
procedure TForm1.Button1Click(Sender: TObject);
begin
if InitDB('informix','onmcis_online','trans','informix','informix',true) then
showmessage('connect ok');
end;

end.
 
這種錯誤一般是在調用完沒有關畢數據集所引起的.
在關閉時把__db.close,就行了.
 
在DLL里面写一个关闭数据库的函数
在程序退出时显式调用该函数即可。
 
[:(]可是,我在程序中已经用了__db.close,难道不可以吗?就上面的程序,
我还没有来得及用数据集耶。
 
我这里试了没有问题
 
to xianjun:能将你的测试程序发给我吗?
dbjam@netease.com
 
Dbjam,天!我昨天打了半天,难道我的没有贴上来??!
你将stdcall去掉,就不会出现错误了。
照这样来:
function InitDB(Driver,Service,Database,UserName,Password:pChar;Check:Boolean):Bool;export;
 
还是不行呀,我把safecall,stdcall,pascal,...都试过了,问题都是一样.
如果不加任何参数的话, 在调用完程序就立即出错.
 
zhangkan,
function InitDB(Driver,Service,Database,UserName,Password:pChar;Check:Boolean):Bool;export;
我觉得在Dll中不加stdcall参数是不可能的
 
to Dbjam,那我想也许是你的程序哪儿有问题,我想应该是指针的问题。我测试了三种。一
是不传任何参数,只传一个回值,不出错;二是传一个参数PCHAR,调用后出错,去掉stdcall,
不出错。于是,我再加上你的类似代码,去掉stdcall,也不出错了,先前出错。因为我并没
有照着贴上你的代码,你若是要的话,留下一贴,我可以将我测试的例子发给你。
to hsw:不加也不会有问题呀。我有两个程序调用DLL,我就没有加上stdcall,也正常运行。
我看书上说写DLL要加上,但我看许多别人的例子,也没有加上。实际上对这个stdcall,我
也还不是很了解,比较模糊,哪位能精确地解释一下就好了。
 
to zhangkan: 不知道怎么搞的,用其他的东西没有问题,就是打开BDE的Database后,即时已经
Free掉,在exe程序退出的时候就是会出错,我查过数据库的连接也已经关闭了.
我的邮件是:dbjam@netease.com
 
试试将调用程序的句柄传入dll中,并将句柄赋予dll的句柄。
 
首先,你不要在DLL执行这段看能不能过:
__db:= TDatabase.Create(nil);
__db.DatabaseName := 'TransTest';
__db.DriverName := Driver;
__db.params.clear;
__db.Params.Add('server name='+Service);
__db.Params.Add('database name='+Database);
__db.Params.Add('user name='+Username);
__db.Params.Add('password='+password);
__db.LoginPrompt := false;
try
__db.Open; // / 如果注释掉这两行,主程序退出不会出错
__db.close; // /
result:=true;
except
end;
__db.free;
end;
我怀疑是你这段有问题! 因为我只是改了你的_DB的几个参数而已
其他都一样就过了。
 

__db:= TDatabase.Create(nil);
这样设置__db的Owner为nil也可以吗?
不好吧
 
谢谢大家的帮助,虽然没有找到最后的答案,但是我决定结束这个问题.原因是:
1.即使可以在Dll中使用BDE,但无法保留BDE的连接,而每次使用的连接时间又很长,
因而我决定使用.Bpl发布了.
2.如果成功,但发布时需要BDE驱动程序,给Delphi以外的程序使用的意义不是太大,
这样我不如用ADO,更通用一些
3.如果对这个问题大家还有更好的建议,别忘了通知我一声握dbjam@netease.com
 
[green]请教:
使用.Bpl发布了.是怎么做的?能告诉我? afeisky@163.com
thank[/green]
 

Similar threads

S
回复
0
查看
3K
SUNSTONE的Delphi笔记
S
S
回复
0
查看
2K
SUNSTONE的Delphi笔记
S
S
回复
0
查看
844
SUNSTONE的Delphi笔记
S
顶部