dll ADODB 动态调用的问题(100)

  • 主题发起人 主题发起人 keyii
  • 开始时间 开始时间
K

keyii

Unregistered / Unconfirmed
GUEST, unregistred user!
刚刚开始学习dll调用。请大家帮忙看看,为什么老提示错误。//dll代码library Synchronization;{ 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 SysUtils, ADODB, windows, StrUtils, Classes;{$R *.res}//取得服务器的时间function GetServerDateTime(ADOConn:TADOConnection):PChar;stdcall;var ADOQ :TADOQuery;begin ADOQ := TADOQuery.Create(nil); with ADOQ do begin ADOQ.Connection := ADOConn; Close; Sql.Clear; Sql.Add('select GetDate() as FDate'); try open; Result := Pchar(formatdatetime('yyyymmddhhmmss',FieldValues['FDate'])); except Result := Pchar('00000000000000'); end; end;end;//同步到本机 0 错误 1 正确function Syn(SDateTime:PChar):integer;stdcall;var sysTime: TSystemTime;begin Result := 1; with sysTime do begin wYear := StrToInt(LeftStr(SDateTime, 4)); wMonth := StrToInt(Copy(SDateTime, 5, 2)); wDay := StrToInt(Copy(SDateTime, 7, 2)); wHour := StrToInt(Copy(SDateTime, 9, 2)); wMinute := StrToInt(Copy(SDateTime, 12, 2)); wSecond := StrToInt(RightStr(SDateTime, 2)); wMilliseconds := 0; end; if not SetLocalTime(sysTime) then Result := 0;end;exports GetServerDateTime, Syn; beginend.//主程序procedure TMainForm.Edit1Click(Sender: TObject);type TIntFunc=function(ADOConn:TADOConnection):PChar;stdcall; //function Syn(SDateTime:PChar):integer;stdcall;var Th:Thandle; Tf:TIntFunc; Tp:TFarProc;begin Th:=LoadLibrary('Synchronization.dll'); {装载DLL} if Th>0 then try Tp:=GetProcAddress(Th,PChar('GetServerDateTime')); if Tp<>nil then begin Tf:=TIntFunc(Tp); Edit1.Text:=Tf(dm.ADOConnection1); {调用GetServerDateTime函数} end else ShowMessage('GetServerDateTime函数没有找到'); finally FreeLibrary(Th); {释放DLL} end else ShowMessage('Synchronization.dll没有找到');end;//目的很简单,就是在dll里面通过使用主程序的ADOconnection1来得到数据库服务器的时间,显示在edit1.text。
 
提示什么错误?
 
CoInitialize?
 
http://www.programbbs.com/bbs/UploadFile/200933017242390798.bmphttp://www.programbbs.com/bbs/UploadFile/200933017244928813.bmp不知道怎么发图片,以上两个图片是错误提示信息。具体的在http://www.programbbs.com/bbs/view12-18962-1.htm请朋友们帮忙,楼上的方法可能成功,但没有看太懂。
 
delphi的ADO组件是封装微软公司的ADO组件。微软公司的ADO组件是Com接口的。像你这样在Dll中调用Com接口,很容用出错的。什么没有初始化类库,没有初始化Com接口,我试过了,都不好用。最后还是用了List对象,把Adoconnection 保存到List里,再到Dll里通过查找AdoConnection在List里的地址,再通过转换为控件。然后使用,没有错了。郁闷的很,我想起那段处理这个问题日子,难熬呀。我都不想提。简单说说思路。在你的主程序里,把ADOConnection 保存到TStringList里,然后把TStringList作为参数传送到Dll里,在Dll里再定义一个TStringList,然后再把传入的TStringList赋值到Dll里的TStringList,然后在Dll里的TStringList查找你要的ADOConnection,然后赋值到你在Dll定义的ADOConnection,OK.
 
楼主说的错误是程序退出的时候出错。解决方法:首先看一个Win API函数UINT GetSystemDirectory( LPTSTR lpBuffer, // address of buffer for system directory UINT uSize // size of directory buffer );向这些返回字符串的Win API函数,大部分都是以参数(传地址)的方式返回,而不是直接以函数名返回字符串,而且这类函数的调用方法都是调用者分配字符内存,分配完后再调用这类函数。改正后的代码:library Synchronization;{ 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 SysUtils, ADODB, windows, StrUtils, Classes;//取得服务器的时间procedure GetServerDateTime(ADOConn:TADOConnection;vRs:PChar);stdcall;var ADOQ :TADOQuery; s:string;begin ADOQ := TADOQuery.Create(nil); with ADOQ do begin try ADOQ.Connection := ADOConn; Sql.Clear; Sql.Add('select GetDate() as FDate'); Open; s:= FormatDateTime('yyyymmddhhmmss',FieldValues['FDate']); StrCopy(vRs,PChar(s)); finally Free; end; end;end;exports GetServerDateTime;beginend.procedure TForm1.Button1Click(Sender: TObject);type TCallProc=procedure(ADOConn:TADOConnection;vRs:PChar);stdcall;var hDLL:THandle; CallProc:TCallProc; vRs:array[0..255] of char;//调用者分配内存begin hDLL:=LoadLibrary('Synchronization.dll'); {装载DLL} if hDLL>0 then try CallProc:=GetProcAddress(hDLL,PChar('GetServerDateTime')); if @CallProc<>nil then begin CallProc(ADOConnection1,vRs); {调用GetServerDateTime函数} edit1.Text:=vRs; end else ShowMessage('GetServerDateTime函数没有找到'); finally FreeLibrary(hDLL); {释放DLL} end else ShowMessage('Synchronization.dll没有找到');end;delphi的DLL功能非常强大,很多人自己不会用,一出现错误,就说delphi的问题,其实还是自己的问题。
 
感谢大家的帮助,用wangdonghai的代码测试没有发现问题,再好好理解一下。
 

Similar threads

后退
顶部