dll 动态调用数据库查询窗口中TQery设置问题!(在线等待) (100分)

  • 主题发起人 主题发起人 TMXYB
  • 开始时间 开始时间
T

TMXYB

Unregistered / Unconfirmed
GUEST, unregistred user!
我在gzan_chax_dll.dll中动态调用show_gzap_chax过程(此过程调用一个数据库查询窗口)时编译通过,但运行时出现错误
错误信息:Access Violation at adress 00000000,Read of address 00000000
程序代码如下:
procedure Tmain_rc_Form.Query_data_actionExecute(Sender: TObject);
var libhandle: Thandle;
show_gzap_chax:procedure (Ahandle:Thandle;DataSetHandle:Integer);stdcall;
begin
libhandle := loadlibrary('gzan_chax_dll.dll');
try
if libhandle = 0 then
raise exception.Create('对不起!查询的动态连接库文件‘gzan_chax_dll.dll’丢失,请重新安装该文件!');
@show_gzap_chax := getprocaddress(libhandle,'show_gzap_chax');
if not (@show_gzap_chax = nil) then
[red]show_gzap_chax(main_rc_Form.Handle, INTEGER(Data_Module.gongz_anp_Query))//经调试此句出现错误![/red]
else
raiselastwin32Error;
finally
freelibrary(libhandle);
end;

end;
经查,并无大小写错误,如改为静态调用没有任何问题,请问是何故?
 
不一定是调用DLL出错,
main_rc_Form对象是否真的存在?
main_rc_Form.Handle.Handle是否真的有效?
Data_Module是否存在?
Data_Module.gongz_anp_Query是否存在?
都是可能出问题的。
你觉得呢?
 
但静态调用并无问题,说明上述对象都存在
 
你的静态调用是指?
1。不通过DLL方式,直接uses unit
2。将函数申明为external 'filename.dll';
???
 
静态调用如下:
.............
............
procedure show_gzap_chax(Ahandle:Thandle;DataSetHandle:Integer);far;external 'gzan_chax_dll.dll'
implementation
...............
procedure Tmain_rc_Form.Query_data_actionExecute(Sender: TObject);
begin
show_gzap_chax(main_rc_Form.Handle, INTEGER(Data_Module.gongz_anp_Query));
end;

以上代码成功,并且能进行如期效果的查询。但动态就不行了,主要是考虑到要减少程序的SIZE!
 
等等,我试试。
 
dll代码如下:
library ppp;
uses
SysUtils,
Classes;
{$R *.RES}
function pp(i: Integer): Integer;
begin
Result := i + i;
end;

exports pp;
begin
end.

调用代码如下:
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;
ft = function(i: Integer): Integer;
var
Form1: TForm1;
//function pp(i: Integer): Integer;
external 'ppp.dll';
implementation
{$R *.DFM}
procedure TForm1.Button1Click(Sender: TObject);
var
hLib: THandle;
pp: ft;
begin
hLib := LoadLibrary('ppp.dll');
if hLib = 0 then
ShowMessage('对不起!查询的动态连接库文件‘gzan_chax_dll.dll’丢失,请重新安装该文件!')
else
@pp := GetProcAddress(hLib, 'pp');
if not(@pp = nil) then
ShowMessage(IntToStr(pp(12)));
end;

end.

没问题啊!
 
我再试一下,看我的程序使用ShowMessage(IntToStr(pp(12)));
有无问题。
 
我的程序使用ShowMessage(IntToStr(pp(12)));也没有问题,看来问题是不是出在窗体的程序上;但为什么静态调用友可以呢?
 
在DLL操纵APP的对象应该不是个好主意。
 
问题查出来了,看来是我的dll 中 show_gzap_chax窗口中的TQuery 在Open 时出错,这下我就没辙了。 坏蟑螂,你能不能帮我看看。
我的Dll 文件如下:
[red]————————————————————[/red]
[red]—————库文件———————[/red]
library gzan_chax_dll;
uses
SysUtils,
Classes,
gzap_chax_Unit in 'gzap_chax_Unit.pas' {gzap_chax_Form},
gzan_chax_dll_Unit in 'gzan_chax_dll_Unit.pas';
{$R *.RES}
exports
show_gzap_chax;
begin
end.
[red]————————————————————[/red]
[red]——————对应的UNIT————————[/red]
unit gzan_chax_dll_Unit;
interface
uses Windows, Messages, SysUtils, Classes, Dialogs, Forms, Db, DBTables;
procedure show_gzap_chax(Ahandle:Thandle;DataSetHandle:Integer);export;
implementation
uses gzap_chax_Unit;

procedure show_gzap_chax(Ahandle:Thandle;DataSetHandle:Integer);
var gzap_chax_Form:Tgzap_chax_Form;
begin
Application.handle:=Ahandle;
gzap_chax_Form:=Tgzap_chax_Form.create(Application);
try
gzap_chax_Form.the_query:=Tquery(DataSetHandle);
[blue]gzap_chax_Form.the_query.Open;[/blue] //此句有问题!
gzap_chax_Form.showmodal;
finally
gzap_chax_Form.free;
end;
end;

end.
[red]————————————————————[/red]
gzap_chax_unit(gzap_chax_Form)中没有函数或过程导出,是一个有TQUERY的窗口,我将TQUERY的databasename 设为了我的主程序的database 的别名,将Sessionname 设为了主程序的Tsession 的名字,SQL为‘slect * from aaa’,看还有什么问题?是不是Session的问题,具体该如何修改?
为什么静态调用又没问题?
 
感谢坏蟑螂的回答,经管没有最终解决问题,但也启发不少。
 
首先,我认为你有几个地方不妥。
1。我一直纳闷,你为什么要传一个窗口句柄进去呢?不传句柄照样可以Show或者ShowModal啊?
(请看下面我的代码)
2。和VC不一样,Delphi中Application.Handle和主窗口的Handle是两回事。看你的样子,你
是不是想传Application.Handle进去?而你传入的参数是main_rc_Form.Handle。在Dll内
部,却又把它赋给了Application.handle。
3。而且,EXE中的Application对象和Dll中的Application对象也是两回事
你为什么要去改DLL的Application.handle呢?根本没有作用的,因为DLL没有分配“主窗口句柄”。
4。再者,本来创建一个Tgzap_chax_Form的同时,就已经创建了一个the_query作为其子对象,
再将一个TQuery对象赋值给它,就与原来的the_query失去了联系(内存泄漏?)。除非你
在设计Tgzap_chax_Form时,没有拖放一个Query控件在其上,the_query只是一个域。
 

Similar threads

S
回复
0
查看
3K
SUNSTONE的Delphi笔记
S
S
回复
0
查看
2K
SUNSTONE的Delphi笔记
S
D
回复
0
查看
1K
DelphiTeacher的专栏
D
后退
顶部