乡下人产国偷v产偷v自拍,国产午夜片在线观看,婷婷成人亚洲综合国产麻豆,久久综合给合久久狠狠狠9

  • <output id="e9wm2"></output>
    <s id="e9wm2"><nobr id="e9wm2"><ins id="e9wm2"></ins></nobr></s>

    • 分享

      函數(shù)調(diào)用約定

       TUBOSS 2014-09-30

      函數(shù)調(diào)用約定包括傳遞參數(shù)的順序,誰負(fù)責(zé)清理參數(shù)占用的堆棧等,例如 :

        參數(shù)傳遞順序 誰負(fù)責(zé)清理參數(shù)占用的堆棧
      __pascal 從左到右 調(diào)用者
      __stdcall 從右到左 被調(diào)函數(shù)
      __cdecl 從右到左 調(diào)用者

      調(diào)用函數(shù)的代碼和被調(diào)函數(shù)必須采用相同的函數(shù)的調(diào)用約定,程序才能正常運(yùn)行。在Windows上,__cdecl是C/C++程序的缺省函數(shù)調(diào)用約定。

      在有的cpu上,編譯器會用寄存器傳遞參數(shù),函數(shù)使用的堆棧由被調(diào)函數(shù)分配和釋放。這種調(diào)用約定在行為上和__cdecl有一個共同點:實參和形參數(shù)目不符不會導(dǎo)致堆棧錯誤。

      不過,即使用寄存器傳遞參數(shù),編譯器在進(jìn)入函數(shù)時,還是會將寄存器里的參數(shù)存入堆棧指定位置。參數(shù)和局部變量一樣應(yīng)該在堆棧中有一席之地。參數(shù)可以被理解為由調(diào)用函數(shù)指定初值的局部變量。

      _stdcall與_cdecl的不同

      a. 默認(rèn)支持:VC默認(rèn)使用_cdecl。所以如果需要使用_stdcall,可采用兩種方法:(1)可以在函數(shù)名前手工添加,只對單一函數(shù)有效 (2)直接修改工程屬性(C/C++ > Advanced > Calling Convention)來一次性配置所有的函數(shù)

      b. 功能不同: _cdecl可實現(xiàn)變長參數(shù)列表

      c. 代碼大?。篲stdcall更小

      d. 速度不同: _cdecl更快(代碼更多當(dāng)然意味著運(yùn)行更快,有點像內(nèi)聯(lián)函數(shù))

      e. 誰負(fù)責(zé)恢復(fù)堆棧:_cdecl主調(diào)用函數(shù)進(jìn)行參數(shù)壓棧并且恢復(fù)堆棧;_stdcall主調(diào)用函數(shù)進(jìn)行參數(shù)壓棧,被調(diào)函數(shù)恢復(fù)堆棧;這也正是產(chǎn)生
         a). 不同代碼大小的原因:如果使用_cdecl的函數(shù)多次調(diào)用同一函數(shù),就要產(chǎn)生多份恢復(fù)碼。
         b). 功能不同的原因:實現(xiàn)變長參數(shù)列表。一份恢復(fù)碼只能將一種長度的參數(shù)表出棧,所以要對不同長度的參數(shù)表堆?;謴?fù),必須要有多份代碼,所以變長參數(shù)必須有主調(diào)函數(shù)恢復(fù)(所以是_cdecl)。

      f. 產(chǎn)生的函數(shù)名不同:

      _stdcall調(diào)用約定在輸出函數(shù)名前加上一個下劃線前綴,后面加上一個“@”符號和其參數(shù)的字節(jié)數(shù),格式為_functionname@number。_cdecl調(diào)用約定僅在輸出函數(shù)名前加上一個下劃線前綴,格式為_functionname。

      g. 使用范圍:

      _stdcall:通常用于DLL的創(chuàng)建(以支持多語言調(diào)用);此外Win32 API函數(shù)皆用_stdcall(比如MessageBox),所以Win32程序中的自定義函數(shù)也做好使用_stdcall。
      _cdecl:非DLL的console程序。

       

      跨語言調(diào)用
      函數(shù)調(diào)用約定只是“調(diào)用函數(shù)的代碼”和被調(diào)用函數(shù)之間的關(guān)系。

      假設(shè)函數(shù)A是__stdcall,函數(shù)B調(diào)用函數(shù)A。你必須通過函數(shù)聲明告訴編譯器,函數(shù)A是__stdcall。編譯器自然會產(chǎn)生正確的調(diào)用代碼。

      如果函數(shù)A是__stdcall。但在引用函數(shù)A的地方,你卻告訴編譯器,函數(shù)A是__cdecl方式,編譯器產(chǎn)生__cdecl方式的代碼,與函數(shù)A的調(diào)用約定不一致,就會發(fā)生錯誤。

      以delphi調(diào)用VC函數(shù)為例,delphi的函數(shù)缺省采用__pascal約定,VC的函數(shù)缺省采用__cdecl約定。我們一般將VC的函數(shù)設(shè)為__stdcall,例如:

      int __stdcall add(int a, int b);

      在delphi中將這個函數(shù)也聲明為__stdcall,就可以調(diào)用了:

      function add(a: Integer; b: Integer): Integer;
      stdcall; external ‘a(chǎn).dll’;

      因為考慮到可能被其它語言的程序調(diào)用,不少API采用__stdcall的調(diào)用約定。

        本站是提供個人知識管理的網(wǎng)絡(luò)存儲空間,所有內(nèi)容均由用戶發(fā)布,不代表本站觀點。請注意甄別內(nèi)容中的聯(lián)系方式、誘導(dǎo)購買等信息,謹(jǐn)防詐騙。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請點擊一鍵舉報。
        轉(zhuǎn)藏 分享 獻(xiàn)花(0

        0條評論

        發(fā)表

        請遵守用戶 評論公約

        類似文章 更多