Delphi 在调用 Win32 API 函数时指针参数的传递问题?(100分)

  • 主题发起人 主题发起人 savetime
  • 开始时间 开始时间
S

savetime

Unregistered / Unconfirmed
GUEST, unregistred user!
例如一个 Win32 API 函数,后面四个参数都是 DWORD 指针:<br>BOOL GetDiskFreeSpace(<br>&nbsp; LPCTSTR lpRootPathName,<br>&nbsp; LPDWORD lpSectorsPerCluster,<br>&nbsp; LPDWORD lpBytesPerSector,<br>&nbsp; LPDWORD lpNumberOfFreeClusters,<br>&nbsp; LPDWORD lpTotalNumberOfClusters<br>);<br><br>在 Windows.pas 中声明如下:<br>function GetDiskFreeSpace; external kernel32 name 'GetDiskFreeSpaceA';<br><br>以下代码编译时会出错(注意参数前的取地址符),并会提示参数是 var 类型的。<br>procedure TForm1.Button1Click(Sender: TObject);<br>var<br>&nbsp; secspclu,bytespsec,freeclu,totalclu,ts,fs:DWord;<br>begin<br>&nbsp; GetDiskFreeSpace('C:/', @secspclu, @bytespsec, @freeclu, @totalclu);<br>&nbsp; fs:=freeclu*secspclu*bytespsec;<br>&nbsp; //磁盘的剩余空间(字节为单位)<br>&nbsp; ts:=totalclu*secspclu*bytespsec;<br>&nbsp; //磁盘的总容量(字节为单位)<br>&nbsp; edit2.text:=formatfloat('###,###',fs);<br>&nbsp; edit1.text:=formatfloat('###,###',ts);<br>&nbsp; //将结果格式化并显示在两个TEdit组件中<br>end;<br><br>Delphi 如何知道 Win32 API 的参数是指针还是值调用呢(什么情况下生成 var 类型的<br>参数)?<br>可能相关的问题是:用 C 写 Win32 应用程序时需要一个 lib 文件定位 Dll 函数,但<br>Delphi 为什么不需要?<br>
 
Delphi已经封装了这个Api函数,只要按Delphi声明的参数类型就行<br>例中不要那些 @,而是变量,变量参数是传指针的
 
var<br>&nbsp;secspclu,bytespsec,freeclu,totalclu,ts,fs:longword; <br>???
 
&gt;&gt;Delphi 如何知道 Win32 API 的参数是指针还是值调用呢(什么情况下生成 var 类型的<br>&gt;&gt;参数)?<br>這個是要約定的, 雙方照約定傳輸! 可參看相觀文檔如 MSDN
 
&gt;&gt; Delphi已经封装了这个Api函数,只要按Delphi声明的参数类型就行<br>&gt;&gt; 例中不要那些 @,而是变量,变量参数是传指针的 &nbsp;<br><br>Delphi 在哪里/是如何 封装 WIN32 API 的?我关心的是这个。<br>
 
Object Pascal 的调用约定是,var 参数传指针,并且参数压堆栈的顺序是和Win32API<br>的顺序一致的,<br>事实上,Win32API的声明函数几乎都是有"pascal"编译开关的<br>BOLL pascal GetDiskFreeSpace(......<br>就是说Win32API的调用约定正好是Object Pascal编译器默认的代码生成规则<br>Winindows.pas 单元的<br>function GetDiskFreeSpace; external kernel32 name 'GetDiskFreeSpaceA';<br>并不是函数声明,而是实现,表示GetDiskFreeSpace是一个外部函数,从kernel32引入<br>函数声明应该在别的地方,形式应如在IDE中敲入函数名后出现的Hint那样<br>从Win32API的原形和Windows.pas的封装声明,可以看出,它们的参数传送方式是<br>一致的.<br>需要注意的是,Windows.pas里第一个参数类型是PChar,而不是String,所有<br>Windows.pas封装的函数,都没有String类型,而是用了PChar,是因为String类型<br>是Delphi特有的<br>---------------------------------------------------------------<br>用 C 写 Win32 应用程序时需要一个 lib 文件定位 Dll 函数,但<br>Delphi 为什么不需要?<br>---------------------------------------------------------------<br>Windows.dcu(Windows.pas)就相当于那个lib, C 是用 .lib(或.h)<br>
 
&gt;&gt;在 Windows.pas 中声明如下:<br>&gt;&gt;function GetDiskFreeSpace; external kernel32 name 'GetDiskFreeSpaceA';<br>错!!这是实现,不是声明。声明在这里:<br>function GetDiskFreeSpace(lpRootPathName: PChar;<br>&nbsp; var lpSectorsPerCluster, lpBytesPerSector, lpNumberOfFreeClusters, lpTotalNumberOfClusters: DWORD): BOOL; stdcall;<br>{$EXTERNALSYM GetDiskFreeSpace}<br><br>这两个加起来就是完整的封装了。<br>
 
原来还有这个,我一直没发现:<br>function GetDiskFreeSpace(lpRootPathName: PChar;<br>&nbsp;var lpSectorsPerCluster, lpBytesPerSector, lpNumberOfFreeClusters, lpTotalNumberOfClusters: DWORD): BOOL; stdcall;<br>{$EXTERNALSYM GetDiskFreeSpace}<br><br>好!
 
呵呵,粗心,其实是个简单问题,我说怎么半天没搞懂楼主说什么,不过原先我也差一点犯这个错误,Delphi的Windows.pas文件中函数绝大部分都是这样申明的,日的,呵呵哈.
 
---------------------------------------------------------------<br>用 C 写 Win32 应用程序时需要一个 lib 文件定位 Dll 函数,但<br>Delphi 为什么不需要?<br>---------------------------------------------------------------<br>&gt;&gt; Windows.dcu(Windows.pas)就相当于那个lib, C 是用 .lib(或.h)<br><br>Windows.dcu 是 DCC32.EXE 编译 Windows.pas 生成的,应该不相当于 C 的 .lib<br>谁给细讲一下。是不是跟 {$EXTERNALSYM GetDiskFreeSpace} 有关,这句是什么<br>意思?<br><br>
 
用 var 申明的就是传指针, delphi 给你做好了。<br>不用再 @ 操作。
 
谢谢各位。
 
后退
顶部