动态调用Dll问题(100分)

  • 主题发起人 主题发起人 Neotian
  • 开始时间 开始时间
N

Neotian

Unregistered / Unconfirmed
GUEST, unregistred user!
procedure TFormMain.ListViewDetailDblClick(Sender: TObject);<br>var<br>&nbsp; str:string;<br>&nbsp; HInst:THandle;<br>&nbsp; FPointer:TFarProc;<br>&nbsp; InitFunc:TInitFunc;<br>begin<br>&nbsp; &nbsp;if ListViewDetail.Selected =nil then exit;<br>&nbsp; &nbsp;str := ListViewDetail.Selected.Caption;<br>&nbsp; &nbsp;if str = 'xxx' then begin<br>&nbsp; &nbsp; &nbsp; HInst := LoadLibrary('UserMgr.dll');<br>&nbsp; &nbsp; &nbsp; if HInst &gt;0 then<br>&nbsp; &nbsp; &nbsp; &nbsp; try<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;@init_user:= GetProcAddress(HInst,'init_user');<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;if @init_user &lt;&gt; nil then begin<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; init_user();<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;end<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;else begin<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; MessageBeep(3);<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; MessageDlg('vvvvvvvvvvvv&amp;iexcl;',mtError,[mbOK],0);<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;end;<br>&nbsp; &nbsp; &nbsp; &nbsp; finally<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;FreeLibrary(HInst);<br>&nbsp; &nbsp; &nbsp; &nbsp; end<br>&nbsp; &nbsp; &nbsp; else begin<br>&nbsp; &nbsp; &nbsp; &nbsp; MessageBeep(3);<br>&nbsp; &nbsp; &nbsp; &nbsp; MessageDlg('mmmmmmmmmmmmm',mtError,[mbOK],0);<br>&nbsp; &nbsp; &nbsp; end;<br>&nbsp; &nbsp;end;<br>为什么上面的代码在编译的时候提示无法识别字符init_user,请告知。<br><br>
 
Delphi例子中的一段代码,你可以参考<br>&nbsp; procedure RegisterCOMServer;<br>&nbsp; var<br>&nbsp; &nbsp; Handle: &nbsp;THandle;<br>&nbsp; &nbsp; RegProc: function: HResult; stdcall;<br>&nbsp; &nbsp; hr: &nbsp; &nbsp; &nbsp;HResult;<br>&nbsp; begin<br>&nbsp; &nbsp; Handle := LoadLibrary(PChar(pcm^.FileName));<br>&nbsp; &nbsp; if Handle = 0 then<br>&nbsp; &nbsp; &nbsp; raise Exception.CreateFmt('%s: %s',<br>&nbsp; &nbsp; &nbsp; &nbsp; [SysErrorMessage(GetLastError), pcm^.FileName]);<br>&nbsp; &nbsp; try<br>&nbsp; &nbsp; &nbsp; RegProc := GetProcAddress(Handle, ProcNames[Cmd]);<br>&nbsp; &nbsp; &nbsp; if Assigned(RegProc) then begin<br>&nbsp; &nbsp; &nbsp; &nbsp; hr := RegProc;<br>&nbsp; &nbsp; &nbsp; &nbsp; if Failed(hr) then<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; raise Exception.Create(<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ProcNames[Cmd] + ' in ' + pcm^.FileName + ' failed.')<br>&nbsp; &nbsp; &nbsp; end<br>&nbsp; &nbsp; &nbsp; else<br>&nbsp; &nbsp; &nbsp; &nbsp; RaiseLastWin32Error<br>&nbsp; &nbsp; finally<br>&nbsp; &nbsp; &nbsp; FreeLibrary(Handle)<br>&nbsp; &nbsp; end<br>&nbsp; end;<br>
 
这条,你的init_user根本就没有定义,是不是应该是init_func<br>&nbsp;@init_user:= GetProcAddress(HInst,'init_user');<br><br>
 
因为你没有声明init_user,看你的调用,应该可以这样声明:<br>var<br>&nbsp; init_user: procedure; stdcall;
 
以下是俺写的一个动态调用dll的demo<br><br>TMyfunc =function(z:integer):integer;stdcall; &nbsp;<br><br>var<br>&nbsp; Form1: TForm1;<br>implementation<br>{$R *.dfm} <br><br>procedure TForm1.Button1Click(Sender: TObject);<br>var<br>&nbsp; ResultVal:integer;<br>&nbsp; MyFunc: TMyFunc;<br>&nbsp; Moudle: THandle;<br>begin<br>&nbsp; &nbsp;Moudle := Loadlibrary('Demo.dll');<br>&nbsp; &nbsp;try<br>&nbsp; &nbsp; if moudle&gt;0 then begin<br>&nbsp; &nbsp;@MyFunc := GetProcAddress(Moudle,'zhang');<br>&nbsp; &nbsp;if not(@MyFunc = nil) then<br>&nbsp; &nbsp; &nbsp;begin<br>&nbsp; &nbsp; &nbsp; ResultVal:=MyFunc(3)<br>&nbsp; &nbsp; &nbsp; showmessage(intTostr(ResultVal));<br>&nbsp; &nbsp; &nbsp; end;<br>&nbsp; &nbsp; else<br>&nbsp; &nbsp; &nbsp; showmessage('function error'); &nbsp; <br>&nbsp; &nbsp; end<br>&nbsp; &nbsp;else<br>&nbsp; &nbsp; showmessage('dll not fount');<br>&nbsp; &nbsp;finally<br>&nbsp; &nbsp;FreeLibrary(Moudle);<br>&nbsp; &nbsp;end;<br>end;<br><br>
 
init_user: procedure; stdcall;<br>这个到不一定非要加stdcall,主要看你的DLL是如何建立的,是使用何种语言,如果不是Delphi一般需要加。<br>如果是Delphi,需要和动态库里面的声明保持一致。
 
怎么能 @init_user:= xxxxxx 呢<br>@是取地址,不能这样赋值<br>init_user:= 还差不多<br>
 
to pipi<br>如果init_user是过程或者函数类型,这样写可以避免歧义。如果过程或者参数<br>类型作为左值,推荐这样写,尽管不这样写也可以。
 
今天在看《object pascal》。<br><br>发现Assigned很冷门,但是看看VCL源代码用的很多。<br><br>在这里可以检查过程是否赋值<br><br>
 
后退
顶部