首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >_imp和__imp有什么区别?

_imp和__imp有什么区别?
EN

Stack Overflow用户
提问于 2012-06-28 08:58:05
回答 1查看 4.2K关注 0票数 9

在Qt Creator中工作时,当我尝试使用MinGW链接到MSVC编译库时,我遇到了一个有趣的错误。链接器抱怨缺少一个符号,就像_imp_FunctionName一样。当我意识到这是由于缺少外部"C",并修复了它,我也运行了/FAcs的MSVC编译器,看看是什么符号。事实证明,它是__imp_FunctionName (这也是我在MSDN和相当多的大师博客网站上读到的方式)。

我完全搞不懂MinGW链接器如何抱怨以_imp开头的符号,但却能够很好地找到它,尽管它是以__imp开头的。一位深厚的编译器魔术师能说明这一点吗?我使用的是Visual Studio 2010。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2012-06-28 20:02:26

这在工作中是相当简单的标识符修饰。imp_前缀是由编译器自动生成的,它导出一个允许优化绑定到DLL导出的函数指针。根据语言规则,imp_以前导下划线为前缀,这是必需的,因为它位于全局名称空间中,由实现生成,否则不会出现在源代码中。所以你得到了_imp_

接下来发生的事情是编译器修饰标识符,以允许链接器捕获声明不匹配的内容。非常重要,因为编译器不能诊断模块之间的声明不匹配,并且在运行时自己诊断它们是非常痛苦的。

首先是C++装饰,这是一个非常复杂的支持函数重载的方案。它生成看起来很奇怪的名字,通常包括很多?和@字符作为参数和返回类型的额外字符,以便重载是明确的。然后是C标识符的修饰,它们基于调用约定。cdecl函数只有一个前导下划线,stdcall函数有一个前导下划线和一个尾随的@n,它允许在参数声明不匹配之前诊断它们不平衡堆栈。64位代码中没有C修饰,只有一种调用约定(幸运的是)。

所以你得到了链接器错误,因为你忘了指定C连接,链接器被要求将重修饰的C++名称与轻微修饰的C名称相匹配。然后你用extern "C"修复了它,现在你得到了为cdecl添加的单个下划线,把_imp_变成了__imp_

票数 30
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/11236789

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档