百度360必应搜狗淘宝本站头条
当前位置:网站首页 > 技术文章 > 正文

.NET9 FCall/QCall调用约定(.net 调用存储过程)

ccwgpt 2025-06-30 15:01 5 浏览 0 评论

蓝字 江湖评谈设为关注




前言

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)的函数,在托管里面的调用。


相关推荐

Xtreme套件Xtreme Suite Pro正式发布v17.0.0

Codejock软件公司的Xtreme套件(XtremeSuite)包含了三种流行的组件:Xtreme命令工具栏(XtremeCommandBars)——把需要创建的具有改进对接算法的所有组件...

Wine能不能跑Win程序?信创操作系统下运行Windows应用的条件!

原文链接:「链接」Hello,大家好啊,今天给大家带来一篇信创操作系统上使用Wine运行Windows应用程序的条件的文章,欢迎大家分享点赞,点个在看和关注吧!在日常使用国产信创操作系统(如统...

VC界面开发组件Xtreme Toolkit Pro全新发布v17.0.0

Codejock软件公司的XtremeToolkitPro是屡获殊荣的VC界面库,是MFC开发中最全面界面控件套包,它提供了Windows开发所需要的11种主流的VisualC++MFC控件,...

机器视觉软件开发新人入门必看 --机器视觉软件开发学习路径

机器视觉是机械、运动、控制、光学、软件、算法于一体的交叉学科,对于学工科的人来说,机械、运动、控制都有一定的了解,对于软件、算法、光学不是很了解。一台设备,有一个到二个机械设计师或者结构工程师,那么这...

数控变频器的研究与实现(数控变频器的研究与实现思考题)

一般变频器具有两种控制方式:控制面板控制方式和串行通信数据控制方式。控制面板控制方式利用变频器自带控制面板进行手动操控,一般应用于非自动控制场合。在自动化程度越来越高的工业生产现场以及机电一体化的数控...

实用 | 分享几个非常实用的开源项目

前言本次分享几个实用的、值得学习使用的嵌入式相关开源项目,下面列举的这些基本上都在本公众号分享过,详细介绍及使用可查看往期笔记。protobufProtocolBuffers,是Google公司开发...

Windows桌面应用程序常用开发框架的设计案例全面展示

Windows桌面应用程序是我们日常生活中不可或缺的一部分,而开发这些应用程序需要使用相应的框架。本文将全面介绍常用的Windows桌面应用程序开发框架,帮助您了解并选择适合的开发工具。一、原生的Wi...

.NET9 FCall/QCall调用约定(.net 调用存储过程)

蓝字江湖评谈设为关注前言FCall/Qcall是托管与非托管之间的调用约定,双方需要一个契约,以弥合彼此的互相/单向调用。非托管调用约定先了解下非托管约定,一般有四种,分别为thiscall,std...

BCGControlBar Pro for MFC v24.4正式发布

BCGControlBar(BusinessComponentsGalleryControlBar)专业版是MFC的一个扩展库,您可以用来构建类似于MicrosoftOffice2000/X...

MFC多文档视图(mfc 多文档)

你可以因为现任不好而分手,但千万不要认为别人更好,永远有人更好,眼下便是更好。。。----网易云热评一、多文档视图架构程序1、特点:可以管理多个文档。(可以有多个文档类对象)2、相关类CWinA...

MFC扩展库BCGControlBar Pro v33.5新版亮点:Ribbon Bar等全新升级

BCGControlBar库拥有500多个经过全面设计、测试和充分记录的MFC扩展类。我们的组件可以轻松地集成到您的应用程序中,并为您节省数百个开发和调试时间。BCGControlBar专业版v3...

山东新华电脑学院4G软件专业明星优秀作品展

项目实战工程师:向修艺年龄:18岁班级:4G软件1501班座右铭:付出才会有收获导师寄语:自学能力和实践能力都非常出色,并且学习认真做事责任心强,是不可多得的人才。相信将来如果能获得机会,发挥自己的...

MFC转QT:Qt基础知识(mfc获取当前日期和时间信息)

1.Qt框架概述Qt的历史和版本Qt是一个跨平台的C++应用程序开发框架,由挪威公司Trolltech(现为QtCompany)于1991年创建。Qt的发展历程:1991年:Qt项目启动1995年...

MFC转QT:Qt高级特性 - 事件系统(mfc读取txt文件每一行数据)

Qt事件处理机制Qt的事件系统是整个框架的核心基础之一,负责处理用户输入、窗口系统消息和应用内部的通信。相比MFC的消息映射系统,Qt的事件处理机制更加灵活和直观。基本概念事件(Event)是Qt框...

MFC用户界面套包BCGControlBar Pro for MFC发布v25.0

BCGControlBar(BusinessComponentsGalleryControlBar)专业版是MFC的一个扩展库,您可以用来构建类似于MicrosoftOffice2000/X...

取消回复欢迎 发表评论: