在Qt Creator中工作时,当我尝试使用MinGW链接到MSVC编译库时,我遇到了一个有趣的错误。链接器抱怨缺少一个符号,就像_imp_FunctionName一样。当我意识到这是由于缺少外部"C",并修复了它,我也运行了/FAcs的MSVC编译器,看看是什么符号。事实证明,它是__imp_FunctionName (这也是我在MSDN和相当多的大师博客网站上读到的方式)。
我完全搞不懂MinGW链接器如何抱怨以_imp开头的符号,但却能够很好地找到它,尽管它是以__imp开头的。一位深厚的编译器魔术师能说明这一点吗?我使用的是Visual Studio 2010。
发布于 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_。
https://stackoverflow.com/questions/11236789
复制相似问题