本人水平有限,02年时候做过1年数据库,如今时隔7年重操旧业义务替单位做个数据库程序,但发现时代进步我没进步,唉,厚颜向各位高手求教,谢谢了!本来都放在数据主程序中是很简单的,但我觉得那样做主程序会显得冗余庞大,所以想将报表打印这块独立出来,然后将数据库查询结果或者query对象本身传递给DLL,在DLL中打印。我试过将query对象本身传递给DLL,但是出地址错误。在网上搜索了下有网友建议: “不要把对象直接传给DLL,而要把对象及其操作包装成普通函数和指针再传递给DLL,就像windows API那样,否则你的程序会死的很残” 以下是他的方法。function OpenSQL(SQL: pchar): pointer;stdcall;
var
qry: TQuery;
begin
qry := TQuery.Create(...);
qry.SQL.Text := SQL;
qry.Open;
Result := qry;
end;
type
RQueryOprs = record
function OpenSQL(SQL: pchar): pointer;stdcall;
function ExecSQL(SQL: pchar): integer;stdcall;
function Eof(Query: pointer): boolean;stdcall;
....
end;
PQueryOprs =^RQueryOprs;
const
query_oprs: RQueryOprs = (
OpenSQL: thispage.OpenSQL;
ExecSQL: thispage.ExecSQL;
Eof: thispage.Eof;
....
);
将query_oprs的地址传入DLL即可,DLL可以通过函数表操作任何类型的SQL数据库
为方便使用可以在DLL中将函数表包装成类上面这个红字部份,函数放在记录类型编译就通不过啊。我以前也试过直接传递QUERY对象指针,但是失败了,他这样行不行?
var
qry: TQuery;
begin
qry := TQuery.Create(...);
qry.SQL.Text := SQL;
qry.Open;
Result := qry;
end;
type
RQueryOprs = record
function OpenSQL(SQL: pchar): pointer;stdcall;
function ExecSQL(SQL: pchar): integer;stdcall;
function Eof(Query: pointer): boolean;stdcall;
....
end;
PQueryOprs =^RQueryOprs;
const
query_oprs: RQueryOprs = (
OpenSQL: thispage.OpenSQL;
ExecSQL: thispage.ExecSQL;
Eof: thispage.Eof;
....
);
将query_oprs的地址传入DLL即可,DLL可以通过函数表操作任何类型的SQL数据库
为方便使用可以在DLL中将函数表包装成类上面这个红字部份,函数放在记录类型编译就通不过啊。我以前也试过直接传递QUERY对象指针,但是失败了,他这样行不行?
解决方案 »
- TreeView从数据库读取数据,添加节点与子节点的问题.
- ACCESS中如何用SQL语句实现通过date来检索datatime类型的数据,经验总结和探讨
- delphi中如何写一个函数,过滤掉字符串中的html代码.
- FileMapping相关的问题,为什么显示不了文件内容?
- midas编程怎么理解?它和用delphi直接连接数据库编程有什么区别?
- 请教一个int64型数据的问题
- Delphi 6的重建问题
- 怎样去掉原代码的只读属性,各位大虾请进
- 急:请教用ODAC连接远程Oracle数据库,无法查询中文字符串的问题!!!!
- 如何恢复sql_server数据库,我只有MDF和ldf文件
- 哪位大侠帮我解答一下。
- 不关闭窗口下如何释放全局变量和局部变量
一个function getqry:query;
begin
qry:=Tquery.create(self);
result:=qry;
end;调用后得到QUERY中的 qry
var
TemQry:Tquery;
TemQry:=getqry;
temqry.assign(查询出结果的数据集);然后 dll中的qry应该就有数据了
另外我自己做了个测试,出pointer错误,请帮我分析下,下面分别是主程序和DLL代码:主程序一个窗体,放了个database1,query1,连接好数据库。unit main;interfaceuses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls, DB, Grids, DBGrids, DBTables;type
Tmainfrm = class(TForm)
catvdb: TDatabase;
Query1: TQuery;
Button1: TButton;
Button2: TButton;
procedure Button1Click(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;var
mainfrm: Tmainfrm;
function passquery(aquery:pointer): pointer;stdcall
external 'printreport.DLL' name 'passquery';
implementationuses Unit2;{$R *.dfm}procedure Tmainfrm.Button1Click(Sender: TObject);
begin
passquery(@query1);
end;end.
DLL 代码,包含一个窗体,上有一个datasource,dbgrid组件显示数据:library printreport;uses
SysUtils,
Classes,
Forms,
dbtables,
unit1 in 'unit1.pas' {Form1};{$R *.res}function passquery(aquery:pointer) :pointer;
var
TemQry:Tquery;
begin
form1:=Tform1.create(nil);
form1.Show; //创建一个窗体,显示主程序query1传递过来的数据。
TemQry:=tquery(aquery^);
//TemQry.Assign(tquery(aquery^));
form1.DataSource1.DataSet:=TemQry;
end; exports
passquery;begin
end.