成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

聊聊 .NET9 FCall/QCall 調用約定

開發 前端
.NET9里面需要在托管和非托管進行相互調用,如果需要調用有效,就必須雙方互有約定。使托管代碼與CLR保持一致。比如FCall會通過一些宏定義打亂堆棧或者寄存器里面的參數進行重新排序,再比如FCall會對返回值,參數,函數名稱進行重新構造。

前言

FCall/Qcall是托管與非托管之間的調用約定,雙方需要一個契約,以彌合彼此的互相/單向調用。

非托管調用約定

先了解下非托管約定,一般有四種,分別為thiscall,stdcall ,cdecl ,fastcall 

thiscall:用特定的寄存器傳遞當前類指針this,由編譯器決定哪個寄存器傳遞this。自清理堆棧,從右往左傳遞參數。

stdcall:一般用于win32 API函數的傳遞方式,自身清理堆棧,從右往左一次傳參。

cdecl:一般用于微軟古老的MFC框架的類的函數傳遞方式,調用者清理堆棧,從右往左依次傳參。

fastcall :用于快速調用方式,規定前幾個參數用寄存器傳遞,多余的參數用棧來傳遞。比如x64前四個參數rcx,rdx,r8,r9等。自身清理堆棧,從右往左傳參。

FCall

.NET9里面需要在托管和非托管進行相互調用,如果需要調用有效,就必須雙方互有約定。使托管代碼與CLR保持一致。比如FCall會通過一些宏定義打亂堆棧或者寄存器里面的參數進行重新排序,再比如FCall會對返回值,參數,函數名稱進行重新構造。FCall就是做這些的,下面看個例子----函數重構。

例子:  

C# code: GC.CollectionCount(0);  
定義:
[MethodImpl(MethodImplOptions.InternalCall)]
private static extern int _CollectionCount(int generation, int getSpecialGCCount);

非托管:

FCIMPL2(int, GCInterface::CollectionCount, INT32 generation, INT32 getSpecialGCCount)
{
    FCALL_CONTRACT;
    _ASSERTE(generation >= 0);
    int result = (INT32)GCHeapUtilities::GetGCHeap()->CollectionCount(generation, getSpecialGCCount);
    FC_GC_POLL_RET();
    return result;
}
FCIMPLEND

一般來說FCall用FCIMPL宏定義開頭,這么做的主要目的是:We align the native code shape to CoreCLR by implementing and using the and macros. These macro are responsible for using correct calling convention and shuffling the order of parameters on the stack. The macros also handle export of undecorated names using the alternatename linker/pragma trick. The downside of the trick is that linker doesn't see the comment pragma if there's no other reference to the .obj file inside a static library. There happened to be exactly two files that have only methods and no other referenced code. As a workaround I added a dummy reference from the .asm files for one function from each of those two files.FCIMPLxFCDECLxFCIMPLx。參考:https://github.com/dotnet/runtime/pull/99430

FCIMPL部分定義:

#define FCIMPL0(rettype, funcname) rettype funcname() { FCIMPL_PROLOG(funcname)
#define FCIMPL1(rettype, funcname, a1) rettype funcname(a1) {  FCIMPL_PROLOG(funcname)
#define FCIMPL1_V(rettype, funcname, a1) rettype funcname(a1) {  FCIMPL_PROLOG(funcname)
#define FCIMPL2(rettype, funcname, a1, a2) rettype funcname(a1, a2) {  FCIMPL_PROLOG(funcname)
#define FCIMPL2VA(rettype, funcname, a1, a2) rettype funcname(a1, a2, ...) {  FCIMPL_PROLOG(funcname)

下面代碼:

源碼:FCIMPL2(int, GCInterface::CollectionCount, INT32 generation, INT32 getSpecialGCCount)
宏定義:
#define FCIMPL2(rettype, funcname, a1, a2) rettype funcname(a1, a2) {  FCIMPL_PROLOG(funcname)
#define FCIMPLEND   FCIMPL_EPILOG(); }

展開如下:

int GCInterface::CollectionCount(int generation,INT32 getSpecialGCCount)
{ 
   //FCIMPL2開頭
   FCIMPL_PROLOG(funcname) 
   //函數主體部分
    FCALL_CONTRACT;
    _ASSERTE(generation >= 0);
    int result = (INT32)GCHeapUtilities::GetGCHeap()->CollectionCount(generation, getSpecialGCCount);
    FC_GC_POLL_RET();
    return result;
    //FCIMPL2結尾
    FCIMPL_EPILOG(); 
}

QCall

QCall一般使用導出標記extern,用托管匹配 CLR調用,運行出結果。調用約定遵循平臺標準.

例子:把長度為len個字節從str復制到desc

[DllImport("QCall", CharSet = CharSet.Unicode)]
private unsafe static extern void Buffer_MemMove(byte* dest, byte* src, [NativeInteger] UIntPtr len);

非托管Qcall

extern "C" void QCALLTYPE Buffer_MemMove(void *dst, void *src, size_t length)
{
    QCALL_CONTRACT;


    memmove(dst, src, length);
}

總結

簡單點來說FCall意思:調用托管函數的時候,可能會調用非托管,FCall就是從托管調用非托管的C#代碼與CLR之間的約定,約定它們如何調用。

QCall的意思:QCall一般用于非托管導出(extern)的函數,在托管里面的調用。

責任編輯:武曉燕 來源: 江湖評談
相關推薦

2024-11-27 13:17:21

2024-02-22 16:58:56

.NET9LinuxConsole

2024-11-20 16:02:47

.NET 9LINQ開發

2022-02-23 09:03:29

JavaScript開發命名約定

2025-05-07 07:23:26

2024-12-09 00:00:06

2009-08-19 15:24:30

.NET命名規范

2009-11-10 15:36:24

VB.NET命名約定

2021-02-07 09:05:56

微服務結構云原生

2025-02-06 13:57:26

2021-07-11 12:12:49

.NETJWTjson

2025-03-05 10:00:00

.NET 9C#開發

2025-01-03 08:29:53

2019-07-23 15:04:54

JavaScript調用棧事件循環

2021-06-08 09:28:12

.Net通知服務

2018-06-20 15:33:44

Spring BootJava 9JDK

2021-07-14 06:45:49

Windows.NetTopshelf

2025-03-03 00:48:12

微軟.NET 9Java

2025-03-03 02:25:00

.NET 9JSON序列化

2020-08-06 11:05:30

函數調用寄存器語言
點贊
收藏

51CTO技術棧公眾號

主站蜘蛛池模板: 国产精品区一区二区三 | 国产91精品在线 | 亚洲精品成人av | 二区在线视频 | 欧美99 | 91久久久久久久久 | 国产精品久久久久久中文字 | 在线观看国产视频 | 久久久性色精品国产免费观看 | 亚洲欧美在线观看 | 999久久久 | 97偷拍视频 | 日本a∨视频 | 精品国产乱码久久久久久88av | 黄色一级大片在线免费看产 | 91porn在线 | 欧美日韩在线成人 | 精品一区二区久久久久久久网精 | www.99热这里只有精品 | 国产高清精品一区二区三区 | www.欧美视频 | 国产精品久久久久久久久污网站 | 丝袜 亚洲 另类 欧美 综合 | 天天躁日日躁性色aⅴ电影 免费在线观看成年人视频 国产欧美精品 | 久久久精品黄色 | 91精品国产91久久久久久吃药 | 精品视频一区二区三区在线观看 | 殴美黄色录像 | 精品99在线 | 国产精品久久国产精品久久 | 日本中文在线视频 | 91免费观看 | 亚洲人成在线播放 | 精品久久久久久久久久 | 国产精品视频一区二区三区不卡 | 国产美女在线观看 | 国产中文在线 | 国产精品久久久爽爽爽麻豆色哟哟 | 国产精品 亚洲一区 | 成人在线观看欧美 | 欧美精品网站 |