而且调用时产生内存读错误码的对话框。下面是DLL源码:
这里面的函数是进行英文的中文译的,从数据库中找中文。关键是ADOConnection1和ADOQuery1的动态生成问题,好象把握得不好,将这个函数放到DELPHI的本地窗体中使用是对的,放在DLL函数中引用就出错,请高手帮助一下呀!!!
library engtochs;{ Important note about DLL memory management: ShareMem must be the
first unit in your library's USES clause AND your project's (select
Project-View Source) USES clause if your DLL exports any procedures or
functions that pass strings as parameters or function results. This
applies to all strings passed to and from your DLL--even those that
are nested in records and classes. ShareMem is the interface unit to
the BORLNDMM.DLL shared memory manager, which must be deployed along
with your DLL. To avoid using BORLNDMM.DLL, pass string information
using PChar or ShortString parameters. }uses
Messages,
Variants,
Graphics,
Controls,
StdCtrls,
SysUtils,
Windows,
DB,
ADODB,
Classes;
{$R *.res}
var
ADOConnection1:TADOConnection;
ADOquery1:TADOQuery;function GetModulePath:string;
var
Buffer : array[0..260] of char;
temp: string;
begin
SetString(temp, Buffer, GetModuleFileName(Hinstance, Buffer, SizeOf(Buffer)));
Result := ExtractFilePath(temp);
end;function englishtochinese(english:pchar):pchar;export;stdcall;
var
s:string;
beginif not fileexists(GetModulePath+'DLMGR.mdb') then
begin
s:='找不到英语词库文件dlmgr.mdb';
englishtochinese:=pchar(s);
exit;
end
else
begin
ADOConnection1.Create(ADOConnection1); //这括号里改为self不行。
ADOquery1.Create(ADOquery1); //这括号里改为self不行。
s:='Provider=Microsoft.Jet.OLEDB.4.0;Data Source='+GetModulePath+'DLMGR.mdb;Mode=Share Deny None;Extended Properties="";Jet OLEDB:Database Password="";Jet OLEDB:Engine Type=5;Jet OLEDB:Database Locking Mode=1;';
ADOConnection1.ConnectionString:=s;
ADOQuery1.Connection:=ADOConnection1;
ADOConnection1.open;
ADOQuery1.SQL.Clear;
ADOQuery1.SQL.Add('select * from 英语字典 where word="'+trim(english)+'"');
ADOQuery1.Open;
if ADOQuery1.RecordCount<1 then
begin
s:='找不到这个单词,请检查拼写';
englishtochinese:=pchar(s);
end
else
begin
while not ADOQuery1.eof do
begin
s:=ADOQuery1.fieldbyname('word').AsString;
s:=s+#13+#10+'['+ADOQuery1.fieldbyname('pronunce').AsString+']';
s:=s+#13+#10+ADOQuery1.fieldbyname('mean').AsString;
s:=s+#13+#10+ADOQuery1.fieldbyname('explain').AsString;
s:=s+#13+#10+ADOQuery1.fieldbyname('example').AsString;
s:=s+#13+#10;
ADOQuery1.Next;
end;
englishtochinese:=pchar(s);
end;
end;end;
exports
englishtochinese;
begin
end.
这里面的函数是进行英文的中文译的,从数据库中找中文。关键是ADOConnection1和ADOQuery1的动态生成问题,好象把握得不好,将这个函数放到DELPHI的本地窗体中使用是对的,放在DLL函数中引用就出错,请高手帮助一下呀!!!
library engtochs;{ Important note about DLL memory management: ShareMem must be the
first unit in your library's USES clause AND your project's (select
Project-View Source) USES clause if your DLL exports any procedures or
functions that pass strings as parameters or function results. This
applies to all strings passed to and from your DLL--even those that
are nested in records and classes. ShareMem is the interface unit to
the BORLNDMM.DLL shared memory manager, which must be deployed along
with your DLL. To avoid using BORLNDMM.DLL, pass string information
using PChar or ShortString parameters. }uses
Messages,
Variants,
Graphics,
Controls,
StdCtrls,
SysUtils,
Windows,
DB,
ADODB,
Classes;
{$R *.res}
var
ADOConnection1:TADOConnection;
ADOquery1:TADOQuery;function GetModulePath:string;
var
Buffer : array[0..260] of char;
temp: string;
begin
SetString(temp, Buffer, GetModuleFileName(Hinstance, Buffer, SizeOf(Buffer)));
Result := ExtractFilePath(temp);
end;function englishtochinese(english:pchar):pchar;export;stdcall;
var
s:string;
beginif not fileexists(GetModulePath+'DLMGR.mdb') then
begin
s:='找不到英语词库文件dlmgr.mdb';
englishtochinese:=pchar(s);
exit;
end
else
begin
ADOConnection1.Create(ADOConnection1); //这括号里改为self不行。
ADOquery1.Create(ADOquery1); //这括号里改为self不行。
s:='Provider=Microsoft.Jet.OLEDB.4.0;Data Source='+GetModulePath+'DLMGR.mdb;Mode=Share Deny None;Extended Properties="";Jet OLEDB:Database Password="";Jet OLEDB:Engine Type=5;Jet OLEDB:Database Locking Mode=1;';
ADOConnection1.ConnectionString:=s;
ADOQuery1.Connection:=ADOConnection1;
ADOConnection1.open;
ADOQuery1.SQL.Clear;
ADOQuery1.SQL.Add('select * from 英语字典 where word="'+trim(english)+'"');
ADOQuery1.Open;
if ADOQuery1.RecordCount<1 then
begin
s:='找不到这个单词,请检查拼写';
englishtochinese:=pchar(s);
end
else
begin
while not ADOQuery1.eof do
begin
s:=ADOQuery1.fieldbyname('word').AsString;
s:=s+#13+#10+'['+ADOQuery1.fieldbyname('pronunce').AsString+']';
s:=s+#13+#10+ADOQuery1.fieldbyname('mean').AsString;
s:=s+#13+#10+ADOQuery1.fieldbyname('explain').AsString;
s:=s+#13+#10+ADOQuery1.fieldbyname('example').AsString;
s:=s+#13+#10;
ADOQuery1.Next;
end;
englishtochinese:=pchar(s);
end;
end;end;
exports
englishtochinese;
begin
end.
解决方案 »
- UpdateBatch的问题?
- 这个SQL语句如何写
- 怎么样才能把DBGrid中的数据转存为Excel的格式啊?
- 请问大家winsock编程时,使用的是delphi带的组件还是直接操作windows api?
- 请看我的数据库恢复代码,错在哪?总是提示‘需要独占数据库才可......’
- 查询的小问题
- 确定richedit中光标的位置(100分哦)
- grid的打印问题?
- 关于SOCKET 通信中的Receivelength 的问题
- 初级问题,如何在DBGRID中添加诸如CHECKBOX,COMBOBOX之类的控件?
- 有没有办法使Query仅得到前100条记录?
- activeform 在浏览器中卷动的问题
CoInitialize(nil);
最后,在程序退出前,用: CoUninitialize;
记得要uses ActiveX;
还有,我习惯用 Create(nil); 或 Create(self);
我在我以前的一个项目中,在dll使用ado相关的组件,没什么问题,如你还有问题,可提出来!你的问题不用提两次啊,还有,用 XXXX.Create(nil); 一般没问题,但要记住,最后自己在最后释放该资源!
我也查了一下,找到了一些答案。
按您说的做了,正确。但是还有一点小问题。就是什么是“程序退出之前”?是不是就是DLL中的函数的结尾处?因为我这是Liberay,不是Application. 目前我的程序在调用多次后,内存占用就大了。另外,为什么在DLL动态库的代码编中不能使用 self? 少引用了什么单元?form 等单元引入了还是不能用:
adoquery1.create(self); 是错的。关键词self不认识。
但具体到你的代码,那就要是在函数的开始与最后加上这些代码,不过,看你的函数,如果多次调用,效率比较差,因为,要多次Create数据连接!!!Self一般指所应用的类自身!象你的函数中,那个self应该是指向Application!!!
ADOConnection1.Create(ADOConnection1);
天啊,这怎么能运行
ADOConnection1 := TADOConnection.Create(nil)
ADOquery1.Create(ADOquery1); //
========
错.....................
您指导得太对了!!!我现在正在为速度快发愁呢。 我的同事说这个查询需要300ms , 不合格,请教您,您一定会有办法帮我提高速度的,能不能给明示一下,如何做成一次初始化,一次清理?动态和静态在代码编写上哪里有区别?我怎么才能一次Create数据连接而不是多次? 非常得感谢您!
想一次create数据连接而不是多次,你要把Adoconnecion连接的建立放在另一个过程或函数里,程序运行时就先调用建立Adoconnection的函数并保存在对象里,查询时传递Adoconnection连接对象即可。程序退出时再销毁Adoconnection连接对象。其实这个连接对象可以在程序里直接建立跟不调用DLL时一样,调用Dll里的查询函数时把
对象传入查询函数即可,这样比较方便。
请教:
1. 我写的是让VC++调用的DLL模块,能在VC++中建立数据库连接再传给DLL中的函数吗?
2. 如果全部写到我的DLL中,分两个函数让C调用,那么这两个函数间如何考虑生存期?即怎么实现打开数据库后不关上,让64个以上的用户不断使用DLL中查询函数时,保证数据库只打开一次再不关上(直到VC++程序关闭时,再通过函数调用来显式地关闭)? 非常感谢能够指教!!!
然后,在你现在提供的函数中只提供查询功能就可!
如果你不想另外一个程序,如VC调用,还要麻烦来调用初始化与退出的函数,你可考虑将你的代码单独写在一个Unit中,然后再在unit中利用
initialization finalization
来达到初始化与退出前的处理!我建议不要传递数据库连接给DLL,那样处理比较麻烦,出错的可能比较大!另外,就是,如果你是用LoadLibrary 来装载dll,那就是动态连接了,函数中的东西,当然在运行完函数就没了,所以,你要声明成全局变量!