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

聊聊 .NET9 FCall/QCall 調(diào)用約定

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

前言

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

非托管調(diào)用約定

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

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

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

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

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

FCall

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

例子:  

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) 
   //函數(shù)主體部分
    FCALL_CONTRACT;
    _ASSERTE(generation >= 0);
    int result = (INT32)GCHeapUtilities::GetGCHeap()->CollectionCount(generation, getSpecialGCCount);
    FC_GC_POLL_RET();
    return result;
    //FCIMPL2結(jié)尾
    FCIMPL_EPILOG(); 
}

QCall

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

例子:把長度為len個字節(jié)從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);
}

總結(jié)

簡單點來說FCall意思:調(diào)用托管函數(shù)的時候,可能會調(diào)用非托管,F(xiàn)Call就是從托管調(diào)用非托管的C#代碼與CLR之間的約定,約定它們?nèi)绾握{(diào)用。

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

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

2024-11-27 13:17:21

2024-02-22 16:58:56

.NET9LinuxConsole

2024-11-20 16:02:47

.NET 9LINQ開發(fā)

2022-02-23 09:03:29

JavaScript開發(fā)命名約定

2025-05-07 07:23:26

2009-08-19 15:24:30

.NET命名規(guī)范

2024-12-09 00:00:06

2009-11-10 15:36:24

VB.NET命名約定

2021-02-07 09:05:56

微服務結(jié)構(gòu)云原生

2025-02-06 13:57:26

2021-07-11 12:12:49

.NETJWTjson

2025-03-05 10:00:00

.NET 9C#開發(fā)

2025-01-03 08:29:53

2019-07-23 15:04:54

JavaScript調(diào)用棧事件循環(huán)

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

函數(shù)調(diào)用寄存器語言
點贊
收藏

51CTO技術棧公眾號

主站蜘蛛池模板: 久久精品视频网站 | 国产一区二区三区色淫影院 | 亚洲综合天堂网 | 亚洲美女一区 | 一区二区三区四区电影 | 亚洲精品视频在线 | 操操网站| 亚洲天堂影院 | 日韩在线国产 | 国产成人免费视频网站视频社区 | 日韩精品在线观看免费 | 国产日韩精品视频 | 老头搡老女人毛片视频在线看 | 在线看亚洲 | 99欧美精品 | 国产欧美日韩二区 | 91麻豆精品国产91久久久更新资源速度超快 | 亚洲国产成人精品女人久久久 | 精品久久久久久久久久久 | 国产精品国产三级国产a | 久久成人国产精品 | 麻豆久久久久久 | 天天操狠狠操 | 久久国产视频网站 | 日本一区二区不卡视频 | 最新中文字幕在线 | 国产精品久久久久久久久久久久久久 | 国产成人精品免费视频 | 亚洲精品99| 久久亚洲国产精品日日av夜夜 | 国产高清视频在线观看 | 欧美一级在线 | 精品久久久久久久久久久下田 | 美日韩免费视频 | 欧美日韩国产在线观看 | 嫩草懂你的影院入口 | 亚洲天堂久久 | 毛片a级| 精品区| 欧美一级全黄 | 成人一区二区三区在线 |