• 几种调用约定


    今天偶然注意了一下C++中malloc的源代码定义,发现有一点疑问,_cdecl 是什么,似曾相识啊,哦,知道了,这和C# 中P/Invoke 有一些关系

    C#调用WINAPI时:[System.Runtime.InteropServices.DllImport("user32.dll")] 其中一个参数涉及到调用约定,即CallingConvention。

    /*调用约定有以下三种:
    
    *_stdcall调用:_stdcall是Pascal程序的缺省调用方式,参数采用从右到左的压栈方式,被调函数自身在返回前清空堆栈。WIN32 Api都采用_stdcall调用方式,这样的宏定义说明了问题:#define WINAPI _stdcall ;按C编译方式,_stdcall调用约定在输出函数名前面加下划线,后面加“@”符号和参数的字节数,形如。
    
    * _cdecl调用:_cdecl是C/C++的缺省调用方式,参数采用从右到左的压栈方式,传送参数的内存栈由调用者维护。_cedcl约定的函数只能被C/C++调用,每一个调用它的函数都包含清空堆栈的代码,所以产生的可执行文件大小会比调用_stdcall函数的大。由于_cdecl调用方式的参数内存栈由调用者维护,所以变长参数的函数能(也只能)使用这种调用约定。关于C/C++中变长参数(…)的问题,笔者将另文详述。由于Visual C++默认采用_cdecl 调用方式,所以VC中中调用DLL时,用户应使用_stdcall调用约定。按C编译方式,_cdecl 条用约定仅在输出函数名前面加上下划线,形如_functionname。
    
     *_fastcall调用:_fastcall调用较快,它通过CPU内部寄存器传递参数。按C编译方式,_fastcall调用约定在输出函数名前面加“@”符号,后面加“@”符号和参数的字节数,形如@functionname@number。
    */
    
    /*DllImport具有五个命名参数: 
    
    *CharSet 参数指示用在入口点中的字符集。如果未指定 CharSet,则使用默认值 CharSet.Auto。 
    
    *CallingConvention 参数指示入口点的调用约定。如果未指定 CallingConvention,则使用默认值 CallingConvention.Winapi。 
    
    *EntryPoint 参数给出 dll 中入口点的名称。如果未指定 EntryPoint,则使用方法本身的名称。 
    
    *ExactSpelling 参数指示 EntryPoint 是否必须与指示的入口点的拼写完全匹配。如果未指定 ExactSpelling,则使用默认值 false。
    
    *PreserveSig 参数指示方法的签名应当被保留还是被转换。当签名被转换时,它被转换为一个具有 HRESULT 返回值和该返回值的一个名为 retval 的附加输出参数的签名。如果未指定 PreserveSig,则使用默认值 true。 
    
    */

    由此可以知道malloc是C++中标准库函数,如果调用某个函数显示是_stdcall function()  则说明调用的是winAPI。

  • 相关阅读:
    Modbus软件开发实战指南 之 开发自己的Modbus Poll工具
    Divide Two Integers-不用'/' '*' '%'操作实现整数的除法
    用最少的砝码称出1到100克的物品
    Binary Tree Inorder Traversal-非递归实现中序遍历二叉树
    leetcode Word Break-单词划分
    位运算题目
    leetcode Single Number II
    leetcode 4Sum
    leetcode 3Sum Closest
    Unique Binary Search Trees-计算表示相同序列的不同BST个数
  • 原文地址:https://www.cnblogs.com/ouweiqideblog/p/3267760.html
Copyright © 2020-2023  润新知