程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> .NET網頁編程 >> C# >> C#入門知識 >> 幾種調用約定

幾種調用約定

編輯:C#入門知識

今天偶然注意了一下C++中malloc的源代碼定義,發現有一點疑問,_cdecl 是什麼,似曾相識啊,哦,知道了,這和C# 中P/Invoke 有一些關系

C#調用WINAPI時:[System.Runtime.InteropServices.DllImport("user32.dll")] 其中一個參數涉及到調用約定,即CallingConvention。

/*調用約定有以下三種:

*_stdcall調用:_stdcall是Pascal程序的缺省調用方式,參數采用從右到左的壓棧方式,被調函數自身在返回前清空堆棧。WIN32 Api都采用_stdcall調用方式,這樣的宏定義說明了問題:#define WINAPI _stdcall ;按C編譯方式,_stdcall調用約定在輸出函數名前面加下劃線,後面加“@”符號和參數的字節數,形如。

* _cdecl調用:_cdecl是C/C++的缺省調用方式,參數采用從右到左的壓棧方式,傳送參數的內存棧由調用者維護。_cedcl約定的函數只能被C/C++調用,每一個調用它的函數都包含清空堆棧的代碼,所以產生的可執行文件大小會比調用_stdcall函數的大。由於_cdecl調用方式的參數內存棧由調用者維護,所以變長參數的函數能(也只能)使用這種調用約定。關於C/C++中變長參數(…)的問題,筆者將另文詳述。由於Visual C++默認采用_cdecl 調用方式,所以VC中中調用DLL時,用戶應使用_stdcall調用約定。按C編譯方式,_cdecl 條用約定僅在輸出函數名前面加上下劃線,形如_functionname。

 *_fastcall調用:_fastcall調用較快,它通過CPU內部寄存器傳遞參數。按C編譯方式,_fastcall調用約定在輸出函數名前面加“@”符號,後面加“@”符號和參數的字節數,形如@functionname@number。
*/
/*DllImport具有五個命名參數: 

*CharSet 參數指示用在入口點中的字符集。如果未指定 CharSet,則使用默認值 CharSet.Auto。 

*CallingConvention 參數指示入口點的調用約定。如果未指定 CallingConvention,則使用默認值 CallingConvention.Winapi。 

*EntryPoint 參數給出 dll 中入口點的名稱。如果未指定 EntryPoint,則使用方法本身的名稱。 

*ExactSpelling 參數指示 EntryPoint 是否必須與指示的入口點的拼寫完全匹配。如果未指定 ExactSpelling,則使用默認值 false。

*PreserveSig 參數指示方法的簽名應當被保留還是被轉換。當簽名被轉換時,它被轉換為一個具有 HRESULT 返回值和該返回值的一個名為 retval 的附加輸出參數的簽名。如果未指定 PreserveSig,則使用默認值 true。 

*/

由此可以知道malloc是C++中標准庫函數,如果調用某個函數顯示是_stdcall function()  則說明調用的是winAPI。

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved