delphi调用dll(100分)

  • 主题发起人 主题发起人 richardsk
  • 开始时间 开始时间
R

richardsk

Unregistered / Unconfirmed
GUEST, unregistred user!
各位大虾,我在delphi程序中调用VC++写的dll,可是无法成功,请指点迷津.
 
什么现象?
 
procedure xxxx(....); stdcall; external 'xx.dll' name '...';<br>注意:有没有stdcall
 
用“快速查看”看dll export的函数名跟你在delphi中的是否一样。
 
混合编程调用DLL函数,注意一下几点;<br>1。参数类型等价,在DELPHI中重新申明时,参数最好用与C兼容的类型。<br>2。STDCALL;<br>3。NAME‘’中的字符串要与C中定义的一模一样,大小写敏感。<br>4。DLL路径找不到。
 
vc有时候也输出cdecl的函数,你把函数名字报出来看看
 
&nbsp;<br>&nbsp; &nbsp; 请查阅WidowsAPI帮助!!
 
用Tdump 把这些DLL文件 里面有的函数输出到一个文本文件里,仔细研究<br>看大小写是否相同
 
如果用静态使用DLL不行的话,可以用LoadLibrary,GetProcAddress来作,跟踪一下看看那里出现问题.如果是用VC写DLL的话,最好不要用CDECL格式,用STDCALL或者FASTCALL比较好
 
根据经验,如果你用的VC动态库是mfc扩展方式的,旧可能造成上述原因,<br>delphi中使用DLL,最好用VC的普通DLL。
 
1. 所需动态连结的 dll 须置放在与执行档同一目录或windows system 目录<br><br>2. 确认 dll export 出来的函式的原型, 以目前的情况而言, 通常只拿得到 c<br><br>语言的函数原型,这时要注意 c 与 object pascal 相对应的型别, 如果需要, 在<br><br>interface 一节定义所需的资料类别<br><br>3. 在 implementation 节中宣告欲使用的函式, 语法大致如下:<br><br>procedure procname(argu...); far; external 'dll档名';<br><br>index n;<br><br>function funcname(argr...): datatype; far;<br><br>external 'dll档名'; index n;<br><br>宣告时, index n 如果不写, 便是参考资料中所谓 import by name 的方式, 此<br><br>时, 由於需要从 dll 的 name table 中找出这个函式, 因此, 连结执行速度比<br><br>import by ordinal稍慢一些, 此外, 还有一种 by new name, 由於我没用过, 您可<br><br>以查一参考资料, 大意是可以 import 後改用另一个程式命名呼叫这个函式<br><br>4. 然後, 呼叫与使用就与一般的delphi 没有两样<br><br>5. 上述是直接写到呼叫dll函式的程式单元中, 此外,也可以将dll的呼叫宣告集<br><br>中到一个程式单元(import unit), delphi 内附的 wintypes, winprocs是一个例子,<br><br>您可以参考一下,同时观察一下 c 与 pascal 互相对应的资料型态<br><br>6. 除了上述的 static import 的方式, 另外有一种 dynamic import 的写法,<br><br>先宣告一个程序类型(procedural-type),程式执行时, 以 loadlibrary() api load<br><br>进来後, 再以 getprocaddress() api 取得函式的位址的方式来连结呼叫, 在object<br><br>pascal language guide p.132-133 有一个例子, 您可以参考看看<br><br>如果要举个例子, 以下是从我以前的程式节录出来的片断:<br><br>(* for cwindows 3.1 *)<br><br>unit ime31;<br><br>interface<br><br>uses<br><br>sysutils, wintypes, winprocs, dialogs;<br><br>type<br><br>(* 必要的资料型态宣告 *)<br><br>tdatentime = record<br><br>wyear, wmonth, wday: word;<br><br>whour, wmin, wsec: word;<br><br>end;<br><br>timepro = record<br><br>hwndime: hwnd; { ime handle }<br><br>dtinstdate: tdatentime; { date and time of installation }<br><br>wversion: word; { the version of ime }<br><br>szdescription: array[0..49] of byte; { description of ime module}<br><br>szname: array[0..79] of byte; { module name of the ime }<br><br>szoptions: array[0..29] of byte; { options of ime at startup}<br><br>fenable: boolean; { ime status; true=activated,false=deactivated }<br><br>end;<br><br>ptimepro = ^timepro;<br><br>function setime(const simefilename: string): boolean; far;<br><br>implementation<br><br>(* begin 呼叫 winnls.dll export 函数的宣告 *)<br><br>function impsetime(hwndime: hwnd; lpimepro: ptimepro): boolean;far; external 'winnls.dll';<br><br>(* end 呼叫 winnls.dll export 函数的宣告 *)<br><br>(* -------------------------------------------------- *)<br><br>(* setime(const simefilename: string): boolean;<br><br>(* ======<br><br>(* 切换到某一特定的输入法<br><br>(*<br><br>(* 传入引数:<br><br>(* simefilename: 输入法 ime 档名, 例: phon.ime;<br><br>(* 空字串: 英数输入法<br><br>(*<br><br>(* 传回值:<br><br>(* true: 切换成功<br><br>(* false: 失败<br><br>(* -------------------------------------------------- *)<br><br>function setime(const simefilename: string): boolean;<br><br>var<br><br>pimepro: ptimepro;<br><br>begin<br><br>result := false;<br><br>if maxavail &lt; sizeof(timepro) then<br><br>begin<br><br>messagedlg('记忆体不足', mtwarning, [mbok], 0);<br><br>exit;<br><br>end<br><br>else<br><br>begin<br><br>new(pimepro);<br><br>try<br><br>if simefilename = '' then (* 空字串, 还原到英数输入法 *)<br><br>pimepro^.szname[0] := 0<br><br>else<br><br>strpcopy(@pimepro^.szname, simefilename);<br><br>result := impsetime(0, pimepro); (* 呼叫 impsetime *)<br><br>finally<br><br>dispose(pimepro);<br><br>end; { of try }<br><br>end;<br><br>end; { of setime }<br><br>end. { of unit win31 }
 
呵呵,抄台湾人的,程式,记忆体,呼叫,这是什么东西啊?
 
接受答案了.
 
前几天我问了一个关于DLL调用的问题,回答还算可以,但我的DLL是用DELPHI写的<br>,该问题的地址是:http://www.gislab.ecnu.edu.cn/delphibbs/dispq.asp?LID=226691<br>
 
后退
顶部