Software 版 (精华区)

发信人: checcy (老巴夺), 信区: Software
标  题: Delphi3.0中的函数调用模式
发信站: 哈工大紫丁香 (Sat Apr  4 00:02:54 1998), 转信

Delphi3.0中的函数调用模式


                   在用Delphi30开发软件时,出现了硬件驱动程
           序 (DLL)中的函数和过程不能正常调用的问题,该硬件由
          英国Schlumberger公司生产,驱动程序用汇编语言编写的
            。其《编程指南》给出的 Microsoft C的示范程序均能正
                常运行。但运行此软件时现出的错误提示为:          

                      Access violation at address ×××××××
                               × in
module……                                  

                  经仔细分析,才发现问题出现在函数调用模式上
                                    
。                                                

                    Delphi30支持五种调用模式:register、cdec
               l、pascal、stdcall和safecall。根据调用模式的不同,
         参数可以通过CPU的寄存器或堆栈传递给函数和过程。reg
          ister模式使用CPU的三个寄存器传递参数,而其它模式则
            用堆栈来传递参数。在register和pascal模式下从左至右
          传递参数,即参数表中最左边的参数最先被求值并传递,
           而最右边的参数最后求值并传递。另三种模式cdecl、std
             call和safecall则从右至左传递参数。这些模式中除了cd
            ecl外,都是由过程和函数在返回时清除堆栈中的参数,
           而对于 cdecl模式,需由调用者在调用结束时清除堆栈中
                                 
的参数。                                          

                       如何选择调用模式,有以下三条规则:        

                      1Delphi30使用register模式作为缺省调用
                          
模式以提高运行效率。                              

                    2如果有调用关系的几个模块是用不同语言编
                       写的,其接口应使用 stdcall模式。                  

                  3如果要实现双界面函数和过程,应使用safec
                                   
all模式。                                        

                      所以解决我们的问题只要选用stdcall模式即可
            , Schlumberger公司的《编程指南》上在Microsoft C环
                     境下的 DLL函数说明(仅举两例)为:                  

                  void(FAR PASCAL *Imp_ Connect)(unsigned s
                               hort far*,short
far*);                          

                      void(FAR PASCAL *Imp_ Init)(short far*,s
                                   hort
far*);                                      

                    相应的在Delphi30下DLL函数引入说明为:  

                   procedure Imp_ Connect(var CardAddress:wor
                          d;var
CardHandle:smallint);stdcall;              

                          procedure Imp_ Init(var Poll_Tab:smallint;
                   var ErrorFlag:smallint;var CardHandle:smallint);st
                                    
dcall;                                            

                    这样修改以后,程序即可正常运行(原来我们没
             有说明调用模式,即使用缺省的 register模式),由此我
          们也可得出一个经验:对一些高版本的新软件,使用时要
          注意改进和扩充,并经常看看帮助文件,定会大有裨益。
                              
(浙江 姜晓东)                                    



-- 
*********************************
Chengyan Che - Software Freelancer
Harbin, P.R.China
mailto: checcy@public.hr.hl.cn
ICQ: 5116726

--
☆ 来源:.哈工大紫丁香 bbs.hit.edu.cn.[FROM: checcy@public.hr.hl.]
[百宝箱] [返回首页] [上级目录] [根目录] [返回顶部] [刷新] [返回]
Powered by KBS BBS 2.0 (http://dev.kcn.cn)
页面执行时间:2.546毫秒