MS VC链接器(link.exe):为什么没有针对32/64位CPU体系结构不匹配的警告? [英] MS VC linker (link.exe): Why no warning for 32/64 bit CPU architecture mismatch?

查看:325
本文介绍了MS VC链接器(link.exe):为什么没有针对32/64位CPU体系结构不匹配的警告?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

(更新:根据汉斯的建议,这是

(Update: As per Hans' suggestion, here's a suggestion to improve link.exe's behaviour, and you can vote for it if you have an account over there.)

好的,我是个傻瓜.一月份,我在计算机Win7 Pro 64 Bit上安装了Oracle.我安装了64位版本.昨天,我使用MSVC Express尝试针对oci.hoci.lib编译并链接一个小型测试程序oci1.c.

Okay, I'm a fool. In January I installed Oracle on my computer, Win7 Pro 64 Bit. I installed the 64 Bit version. Yesterday, using MSVC Express, I tried to compile and link a small test programm oci1.c against oci.h and oci.lib.

cl /nologo /c /I%ORACLE_HOME%\oci\include oci1.c
link /nologo oci1.obj /LIBPATH:%ORACLE_HOME%\oci\lib\msvc oci.lib

我的尝试一直失败,并出现 LNK2019,这意味着未解决的外部函数'function' 中引用的符号'symbol'.有问题的符号(_OCIEnvCreate)当然是由oci.lib提供的,因此链接程序应该能够解决它.

My attempts kept failing with LNK2019, which means unresolved external symbol 'symbol' referenced in function 'function'. The symbol in question (_OCIEnvCreate) is, of course, provided by oci.lib, so the linker should be able to resolve it.

我终于意识到它无法工作,因为我的编译器只有32位,而导入库是64位.如果您是一个傻瓜并且不知道或不记得,那么可以使用dumpbin实用程序来查看它:

It finally dawned on me that it couldn't work because my compiler is 32 bit only, and the import library is 64 bit. If you're a fool and you don't know or remember, then you can see it using the dumpbin utility:

$ dumpbin /headers %ORACLE_HOME%\oci\lib\msvc\oci.lib | head
File Type: LIBRARY
FILE HEADER VALUES
        8664 machine (x64)

$ dumpbin /headers oci1.obj | head
File Type: COFF OBJECT
FILE HEADER VALUES
         14C machine (x86)

到目前为止,太好了.但是我浪费了一些时间,想避免重蹈覆辙.

So far, so good. But I wasted some time and would like to avoid repeating that experience.

虽然不正确,但LNK2019错误消息并不能使您直接朝正确的方向前进.没有警告您正在尝试链接不同CPU架构的二进制文件.

While not incorrect, the LNK2019 error message doesn't lead you straight in the right direction. There's no warning that you're attempting to link binaries for different CPU architectures.

请注意,当您指定X64体系结构时,系统会提示您已指定X86二进制文件:

Note that when you specify the X64 architecture, you are alerted to the fact that you specified X86 binaries:

$ link /machine:x64 /nologo oci1.obj /LIBPATH:%ORACLE_HOME%\oci\lib\msvc oci.lib
oci1.obj : fatal error LNK1112:
Modul-Computertyp "X86" steht in Konflikt mit dem Zielcomputertyp "x64".

但是,当您显式或隐式指定X86体系结构时,没有这样的精确警告:

But there is no such precise warning when you specify the X86 architecture, explicitly or implicitly:

$ link /machine:x86 /nologo oci1.obj /LIBPATH:%ORACLE_HOME%\oci\lib\msvc oci.lib
oci1.obj : error LNK2019: Verweis auf nicht aufgelöstes externes Symbol
  "_OCIEnvCreate" in Funktion "_main".
oci1.exe : fatal error LNK1120: 1 nicht aufgelöste externe Verweise.

我刚刚发现/VERBOSE切换到link.exe ,使用时暗示在我的64位oci.lib中找不到符号.

I just found the /VERBOSE switch to link.exe, which when used hints that no symbols are found in my 64 bit oci.lib.

您是否可以打开其他选项以使链接过程更安全,更简单?

Are there other options you can turn on to make the linking process more, eh, fool-proof?

更新:根据汉斯的回答,我在32位导入库上运行dumpbin,其名称如下所示:

Update: As per Hans' answer, I ran dumpbin on a 32 bit import library, and the names appear as follows:

$ dumpbin /exports D:\Opt\MySQL5.5\lib\libmysql.lib
_load_defaults
_myodbc_remove_escape@8
_mysql_affected_rows@4
_mysql_autocommit@8
_mysql_change_user@16
_mysql_character_set_name@4

在这里我要处理的64位OCI导入库中的名称看起来是未经修饰的:

Whereas the names in the 64 bit OCI import library that I'm dealing with here appear undecorated:

OCIXmlDbFreeXmlCtx
OCIXmlDbInitXmlCtx
ORLRconNativeInt
ORLRvalNativeInt
OraCoreIsPhysicalRawFile
OraMemAlloc

有关X86调用约定的维基百科:

在Windows上下文中为x64体系结构进行编译时(是否 使用Microsoft或非Microsoft工具),只有一个调用 约定-此处描述的约定,以便stdcall,thiscall,cdecl, 现在,fastcall等都一模一样.

When compiling for the x64 architecture in a Windows context (whether using Microsoft or non-Microsoft tools), there is only one calling convention — the one described here, so that stdcall, thiscall, cdecl, fastcall, etc., are now all one and the same.

还与有关名称更改的文章相关.

现在让我明白了.一个唯一的调用约定,因此无需名称修饰,因此在为X86进行编译时无需按照cdecl的下划线.

Makes sense to me now. One and only calling convention, hence no name mangling necessary, hence no leading underscore as per cdecl when compiling for X86.

推荐答案

我认为它只是抱怨缺少符号之前来检查二进制兼容性.通常会首先发生这种情况,因为x64没有任何调用约定,所以x64符号没有下划线.除非您使用Microsoft导入库,否则它们根本不会修饰符号.

I think it simply complains about the missing symbol before getting around to checking the binary compatibility. That will commonly happen first, x64 symbols don't have the leading underscore since x64 doesn't have any calling conventions. Unless you use Microsoft import libraries, they don't decorate the symbols at all.

但是我非常同意,首先遇到兼容性错误会提高生产力.不知道这有多难实现.问问那些知道并可以使其工作的人,将功能请求发布到connect.microsoft.com

But I very much agree, getting the compatibility error first would be much more productive. No idea how hard that is to implement. Ask the guys who know and can make it work like that, post a feature request to connect.microsoft.com

这篇关于MS VC链接器(link.exe):为什么没有针对32/64位CPU体系结构不匹配的警告?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆