`
xpp02
  • 浏览: 1016965 次
社区版块
存档分类
最新评论

VC的函数修饰名

 
阅读更多
VC 中的修饰名(Decoration name)

“C”或者“C++”函数在内部(编译和链接)通过修饰名识别。修饰名是编译器在编译函数定义或者原型时生成的字 符串。有些情况下使用函数的修饰名是必要的,如在模块定义文件里头指定输出“C++”重载函数、构造函数、析构函数,又如在汇编代码里调用“C””或“C ++”函数等。

修饰名由函数名、类名、调用约定、返回类型、参数等共同决定。

    1. 调用约定

调用约定(Calling convention)决定以下内容:函数参数的压栈顺序,由调用者还是被调用者把参数弹出栈,以及产生函数修饰名的方法。MFC支持以下调用约定:

  1. _cdecl

    按从右至左的顺序压参数入栈,由调用者把参数弹出栈。对于“C”函数或者变量,修饰名是在函数名前加下划线。对于“C++”函数,有所不同。

    如函数void test(void)的修饰名是_test;对于不属于一个类的“C++”全局函数,修饰名是?test@@ZAXXZ。

    这是MFC缺省调用约定。由于是调用者负责把参数弹出栈,所以可以给函数定义个数不定的参数,如printf函数。

  2. _stdcall

    按从右至左的顺序压参数入栈,由被调用者把参数弹出栈。对于“C”函数或者变量,修饰名以下划线为前缀,然后是函数名,然后是符号“@”及参数的字节数,如函数int func(int a, double b)的修饰名是_func@12。对于“C++”函数,则有所不同。

    所有的Win32 API函数都遵循该约定。

  3. _fastcall

    头两个DWORD类型或者占更少字节的参数被放入ECX和EDX寄存器,其他剩下的参数按从右到左的顺序压入栈。由被调用者把参数弹出栈,对于“C”函数或者变量,修饰名以“@”为前缀,然后是函数名,接着是符号“@”及参数的字节数,如函数int func(int a, double b)的修饰名是@func@12。对于“C++”函数,有所不同。

    未来的编译器可能使用不同的寄存器来存放参数。

  4. thiscall

    仅仅应用于“C++”成员函数。this指针存放于CX寄存器,参数从右到左压栈。thiscall不是关键词,因此不能被程序员指定。

  5. naked call

    采用1-4的调用约定时,如果必要的话,进入函数时编译器会产生代码来保存ESI,EDI,EBX,EBP寄存器,退出函数时则产生代码恢复这些寄存器的内容。naked call不产生这样的代码。

    naked call不是类型修饰符,故必须和_declspec共同使用,如下:

    __declspec( naked ) int func( formal_parameters )

    {

    // Function body

    }

  6. 过时的调用约定

原来的一些调用约定可以不再使用。它们被定义成调用约定_stdcall或者_cdecl。例如:

#define CALLBACK __stdcall

#define WINAPI __stdcall

#define WINAPIV __cdecl

#define APIENTRY WINAPI

#define APIPRIVATE __stdcall

#define PASCAL __stdcall


表7-1显示了一个函数在几种调用约定下的修饰名(表中的“C++”函数指的是“C++”全局函数,不是成员函数),函数原型是void CALLTYPE test(void),CALLTYPE可以是_cdecl、_fastcall、_stdcall。

表7-1 不同调用约定下的修饰名

调用约定

extern “C”或.C文件

.cpp, .cxx或/TP编译开关

_cdecl

_test

?test@@ZAXXZ

_fastcall

@test@0

?test@@YIXXZ

_stdcall

_test@0

?test@@YGXXZ


分享到:
评论

相关推荐

    获得dll的所有输出函数

    利用这个程序可以得到一个dll的所有输出函数,这没有什么特别的,w32dsm就可以,不过w32dsm输出的是一般人看不懂得“名称修饰”,我这个程序是可以转换为C++函数声明的。 其实,这些功能微软都提供了(undname.exe和...

    VC多线程编程(vs2010Unicode修改版)

    “CWinThread *pWriteW=AfxBeginThread(WriteW,……”中的线程调用函数前加上“::”,修改后“CWinThread *pWriteW=AfxBeginThread(::WriteW,……”,如果WriteW成员函数有static修饰符)或者是全局函数,无需修改。

    DLL输出函数察看(新版本修改了一个错误)

    利用这个程序可以得到一个dll的所有输出函数,这没有什么特别的,w32dsm就可以,不过w32dsm输出的是一般人看不懂得“名称修饰”,我这个程序是可以转换为C++函数声明的。 其实,这些功能微软都提供了(undname.exe和...

    php5.5 zip 32位

    e修饰符是指示preg_replace函数用来评估替换字符串作为PHP代码,而不只是仅仅做一个简单的字符串替换。不出所料,这种行为会源源不断的出现安全问题。这就是为什么在PHP5.5 中使用这个修饰符将抛出一个弃用警告。...

    自己写的dll的简介

    那么由于在.dll文件中的实际文件名会被修饰(具体被修饰的规则可参考函数调用约定详解或者使用VC自带的Depends.exe查看),所以直接找Test是找不到的,这时必须把函数名修改为正确的被修饰后的名称,下面是一种可能...

    VC++6语言参考手册

    录中给出了Visual C++的语法总结、Microsoft 特殊修饰符、编译器COM 支持 类、图表等。第三部分Visual C++ 6.0 预处理器参考手册, 分3 章和1 个附录, 给出了C++ 6.0 的预处理器和预处理器的编译器的编译指示指令...

    高质量C++编程指南

    2.6 修饰符的位置 19 2.7 注释 20 2.8 类的版式 21 第3章 命名规则 22 3.1 共性规则 22 3.2 简单的Windows应用程序命名规则 23 3.3 简单的Unix应用程序命名规则 25 第4章 表达式和基本语句 26 4.1 运算符的优先级 26...

    MFC教程入门知识全集.rar

    1.5 类的继承与protected 访问修饰符 1.5.1 单一继承 (例子代码EX01-03) (图x,没有) 1.5.2 多重继承 1.6 虚函数与多态性 1.7 类的书写规范 1.8 小结 第2 章 Windows 程序内部运行原理 2.1 Windows 应用...

    C/C++笔试题(附答案,华为面试题系列)

    答:函数和变量被C++编译后在符号库中的名字与C语言的不同,被extern "C"修饰的变 量和函数是按照C语言方式编译和连接的。由于编译后的名字不同,C++程序不能直接调 用C 函数。C++提供了一个C 连接交换指定符号...

    c++ 面试题 总结

    1.是不是一个父类写了一个virtual 函数,如果子类覆盖它的函数不加virtual ,也能实现多态? virtual修饰符会被隐形继承的。 private 也被集成,只事派生类没有访问权限而已 virtual可加可不加 子类的空间里有父类...

    PT80-NEAT开发指南v1.1

    NEAT 开 发 指南 文档 适用于 PT80 系列 移动数据终端 版本记录 版本号 版本描述 发布日期 V 1.0 初始版本。 2012-04-12 V1.1 修改前三章内容 2012-09-25 目录 第一章 关于本手册.....................................

    asp.net知识库

    Oracle中PL/SQL单行函数和组函数详解 mssql+oracle Oracle编程的编码规范及命名规则 Oracle数据库字典介绍 0RACLE的字段类型 事务 CMT DEMO(容器管理事务演示) 事务隔离性的一些基础知识 在组件之间实现事务和异步...

Global site tag (gtag.js) - Google Analytics