请问name-mangled是什么意思?

freespider 2003-09-13 12:12:22
请问name-mangled是什么意思?
据说是一种导出方法的的符号,由于没有标准,各个编译厂商都不一样,
哪位大侠能举个例子吗,随便列出两个编译厂商的name-mangled写法
...全文
137 1 打赏 收藏 转发到动态 举报
写回复
用AI写文章
1 条回复
切换为时间正序
请发表友善的回复…
发表回复
aflyinghorse 2003-09-13
  • 打赏
  • 举报
回复
more effective c++:

名变换,就是C++编译器给程序的每个函数换一个独一无二的名字。在C中,这个过程是不需要的,因为没有函数重载,但几乎所有C++程序都有函数重名(例如,流运行库就申明了几个版本的operator<<和operator>>)。重载不兼容于绝大部分链接程序,因为链接程序通常无法分辨同名的函数。名变换是对链接程序的妥协;链接程序通常坚持函数名必须独一无二。
如果只在C++范围内,名变换不会影响你。如果你你有一个函数叫drawline而编译器将它变换为xyzzy,你总使用名字drawLine,不会注意到背后的obj文件引用的是xyzzy的。
如果drawLine位于C运行库中,那就是一个不同的故事了。你的C++源文件包含的头文件中申明为:
void drawLine(int x1, int y1, int x2, int y2);
代码体中通常也是调用drawLine。每个这样的调用都被编译器转换为调用名变换后的函数,所以写下的是
drawLine(a, b, c, d); // call to unmangled function name
obj文件中调用的是:
xyzzy(a, b, c, d); // call to mangled function mame
但如果drawLine是一个C函数,obj文件(或者是动态链接库之类的文件)中包含的编译后的drawLine函数仍然叫drawLine;没有名变换动作。当你试图将obj文件链接为程序时,将得到一个错误,因为链接程序在寻找一个叫xyzzy的函数,而没有这样的函数存在。
要解决这个问题,你需要一种方法来告诉C++编译器不要在这个函数上进行名变换。你不期望对用其它语言写的函数进行名变换,如C、汇编、Fortran、LISP、Forth或其它。(是的,这“其它”中应该包括COBOL,但那时你将得到什么?(Yes, what-have-you would include COBOL, but then what would you have? ))总之,如果你调用一个名字为drawLine的C函数,它实际上就叫drawLine,你的obj文件应该包含这样的一个引用,而不是引用进行了名变换的版本。
要禁止名变换,使用C++的extern 'C'指示:
// declare a function called drawLine; don't mangle
// its name
extern "C"
void drawLine(int x1, int y1, int x2, int y2);
不要以为有一个extern 'C',那么就应该同样有一个extern 'Pascal'和extern 'FORTRAN'。没有,至少在C++标准中没有。不要将extern 'C'看作是申明这个函数是用C语言写的,应该看作是申明在个函数应该被当作好象C写的一样而进行调用。(使用术语就是,extern 'C'意思是这个函数有C链接,但这个意思表达实在不怎么清晰。不管如何,它总意味着一件事:名变换被禁止了。)

69,373

社区成员

发帖
与我相关
我的任务
社区描述
C语言相关问题讨论
社区管理员
  • C语言
  • 花神庙码农
  • 架构师李肯
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧