当前位置: 首页 > news >正文

南昌网站建设 南昌做网站公司南宁推广软件

南昌网站建设 南昌做网站公司,南宁推广软件,企业网站文案外包,企业网站建站 费用在C/C编程中,调用约定(calling conventions)是一组指定如何调用函数的规则。主要在你调用代码之外的函数(例如OS API,操作系统应用程序接口)或OS调用你(如WinMain的情况)时起作用。如果编译器不知道正确的调用约定,那么你很可能会遇到非常奇怪…

      在C/C++编程中,调用约定(calling conventions)是一组指定如何调用函数的规则。主要在你调用代码之外的函数(例如OS API,操作系统应用程序接口)或OS调用你(如WinMain的情况)时起作用。如果编译器不知道正确的调用约定,那么你很可能会遇到非常奇怪的崩溃,因为堆栈将无法正确管理。调用约定用于确保函数在不同平台和编译器之间正确且一致地调用。调用约定有助于标准化编译器的函数调用和参数传递方式,标准化可实现编程语言之间的互操作性。

      并非所有约定都在所有支持的平台上可用,某些约定使用平台特定的实现。在大多数情况下,将忽略在特定平台上指定不支持的约定的关键字或编译器开关,并将使用平台默认约定

      调用约定通常在函数声明或定义时通过特定的关键字或属性指定。例如,在MSVC中,可以使用__cdecl、__stdcall、__fastcall等关键字来指定调用约定。在GCC中,可以使用__attribute__((cdecl))、__attribute__((stdcall))等属性来指定调用约定。在跨平台开发或调用第三方库时,需要特别注意调用约定的匹配

      C/C++中的调用约定是确定以下准则

      (1).如何将参数传递到堆栈。

      (2).谁将清除堆栈,调用者还是被调用者?

      (3).将使用哪些寄存器以及如何使用。

      C++代码在编译阶段结束时转换为目标代码(object code)。然后我们得到目标文件(object file)。目标文件链接在一起以创建二进制文件(如exe、lib、dll)。在创建目标文件之前,我们可以告诉编译器停止并给我们.asm文件。这是将转换为目标文件的汇编文件。不同的调用约定会产生不同的汇编代码(Different calling conventions produce different assembly codes)。

      MSVC支持几种函数的调用约定:"__cdecl"、"__stdcall"、"__fastcall"等,默认情况下MSVC把C语言的函数当作"__cdecl"类型,这种情况下它对该函数不进行任何符号修饰。但是一旦我们使用其它的函数调用约定时,MSVC编译器就会对符号名进行修饰,比如使用"__stdcall"调用约定的函数Add就会被修饰成"_Add@16",前面以"_"开头,后面以"@n"结尾,n表示函数调用时参数所占堆栈空间的大小。使用.def文件可以将导出函数重新命名。当一个DLL被多个语言编写的模块使用时,采用这种方法导出一个函数往往会很有用。我们经常看到Windows的API都采用"WINAPI"这种方式声明,而"WINAPI"实际上是一个被定义为"__stdcall"的宏。微软以DLL的形式提供Windows的API,而每个DLL中的导出函数又以这种"__stdcall"的方式被声明。

      MSVC下不同的调用约定使用时将以下修饰符放置在变量或者函数名称的前面,告诉编译器设置堆栈、推送参数和获取返回值的规则

      1.__cdecl:C declaration,C/C++程序的默认调用约定。是一种"干净"的调用约定,不使用任何特殊指令或寄存器来传递函数参数或返回值。

      (1).参数从右向左依次入栈(因此第一个参数最接近堆栈顶部)。

      (2).调用者负责清理堆栈,即调用者会在返回后弹出所有参数。

      (3).创建比__stdcall更大的可执行文件,因为它要求每个函数调用都包含堆栈清理代码。

      (4).当调用者按照此约定清理堆栈时,我们可以为使用__cdecl调用约定的函数提供可变参数。

      2.__stdcall:Standard Call,Win32 API函数使用的特定于Microsoft的调用约定。

      (1).参数从右向左依次入栈(因此第一个参数最接近堆栈顶部)。

      (2).被调用者(自身)负责清理堆栈,即被调用者在返回前会弹出所有参数。

      3.__fastcall:在__fastcall调用约定中,如果可能的话,参数会被传递给寄存器。

      (1).前两个参数(从左到右的顺序)通过寄存器ECX和EDX传递。其余参数从右向左依次入栈。

      (2).被调用者负责清理堆栈。

      4.__thiscall:仅适用于C++,类内方法使用的默认调用约定。

      (1).参数从右向左依次入栈。

      (2).this指针通过寄存器ECX传递,而不是在堆栈上传递。

      (3).不能对非成员函数使用此调用约定。

      (4).被调用者负责清理堆栈。

      (5).__thiscall只能出现在非静态成员函数上。

      在C/C++中使用调用约定的优点

      1.兼容性:不同的平台和编译器对函数参数的传递方式和返回值的返回方式可能有不同的要求。通过使用特定的调用约定,你可以确保你的代码与不同的平台和编译器兼容

      2.一致性:使用一致的调用约定有助于确保你的代码易于阅读和理解。

      3.优化:某些调用约定旨在比其他调用约定更高效。例如,__fastcall调用约定可以比__cdecl或__stdcall更快,因为它使用寄存器传递函数参数。这对于经常调用的函数尤其有用。

      4.安全性:使用一致的调用约定有助于防止出现诸如堆栈损坏或返回值不正确等错误。

      在C/C++中使用调用约定的缺点

      1.复杂性:使用不同的调用约定会增加代码的复杂性,尤其是在处理具有许多不同功能的大型项目时。这会使代码更难理解和维护。

      2.兼容性问题:如果你使用的调用约定不受特定平台或编译器支持,则可能必须修改代码或使用不同的调用约定。这可能很耗时,并且可能需要进行额外的测试以确保代码仍然正确。

      3.性能开销:某些调用约定可能会带来少量性能开销,尤其是在它们需要额外的指令或寄存器使用时。这对于大多数应用程序来说可能并不重要,但对于高性能代码来说,这可能是一个考虑因素。

      4.可移植性:如果你使用的调用约定特定于特定平台或编译器,则你的代码可能无法移植到其他平台或编译器。如果你想在不同平台上重用代码,或者你正在使用混合环境,这可能会成为一个问题。

     注:以上整理的内容主要来自:

     1. https://www.geeksforgeeks.org

      2. https://www.javatpoint.com

      以下为测试代码:

#include "calling_convention.hpp"
#include <iostream>namespace {#ifdef _MSC_VER
#define CDECL __cdecl
#define STDCALL __stdcall
#define FASTCALL __fastcall
#define THISCALL __thiscall
#else
#define CDECL __attribute__((cdecl))
#define STDCALL __attribute__((stdcall))
#define FASTCALL __attribute__((fastcall))
#define THISCALL __attribute__((thiscall))
#endifint CDECL add_cdecl(int a, int b) { return (a + b); }
int STDCALL add_stdcall(int a, int b) { return (a + b); }
int FASTCALL add_fastcall(int a, int b) { return (a + b); }
class Tmp {
public:int THISCALL add_thiscall(int a, int b) { return (a + b); }
};} // namespaceint test_calling_convention()
{auto ret1 = add_cdecl(1, 2);auto ret2 = add_stdcall(1, 2);auto ret3 = add_fastcall(1, 2);Tmp tmp;auto ret4 = tmp.add_thiscall(1, 2);std::cout << "results: " << ret1 << "," << ret2 << "," << ret3 << "," << ret4 << std::endl;return 0;
}

      GitHub:https://github.com/fengbingchun/Messy_Test

http://www.hkea.cn/news/150008/

相关文章:

  • 百草味网站建设的活动方案营销型企业网站有哪些
  • 论文课程网站 建设背景项目推广方式有哪些
  • 内部网站建设关键词优化推广策略
  • 一个公司可以做几个网站备案贵阳网络推广排名
  • 武汉高端网站建设免费广告网
  • 大理建网站常用于网站推广的营销手段是
  • js怎么做网站跨境电商网站
  • 台州外贸网站建设百度推广费用多少
  • 虚拟机怎么做网站空间培训班管理系统 免费
  • wordpress离线文章发布郑州seo关键词排名优化
  • 龙岗区网站建设中国职业培训在线
  • 南山网站建设外包优化网站
  • 个人怎么做网站推广神起网络游戏推广平台
  • 做网站的关键技术运营推广的方式和渠道有哪些
  • jsp做就业网站网推项目
  • 网站开发的目的和意义重庆seo排名电话
  • 顺义专业建站公司最有效的线上推广方式
  • 大连网站网站搭建制作百度识图 上传图片
  • 给人做网站多少钱黑科技引流推广神器怎么下载
  • 沈阳做网站最好的公司百度快照怎么删除
  • 设置本机外网ip做网站网站免费制作平台
  • 有什么推荐做简历的网站2024的新闻有哪些
  • 申请做网站 论坛版主惠州seo外包服务
  • 网站照片上传不了域名解析ip
  • 胖小七网站建设2022最新国际新闻10条简短
  • wordpress 网站备份厦门seo外包服务
  • 网站建设及推广培训杭州百度快照优化排名
  • 简单手机网站开发软件关键词排名代发
  • visio画网站开发类图注册域名后怎么建网站
  • 道里网站运营培训北京网络营销咨询公司