(更新:根据汉斯的建议,这里是suggestion to improve link.exe
's behaviour,如果你在那边有帐户,你可以投票。)
好的,我是个傻瓜。 1月份,我在我的计算机上安装了Oracle,Win7 Pro 64 Bit。我安装了64位版本。昨天,使用MSVC Express,我尝试编译并链接一个小型测试程序oci1.c
对oci.h
和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
, which means unresolved external symbol 'symbol' referenced in function 'function'失败。当然,有问题的符号(_OCIEnvCreate
)由oci.lib
提供,因此链接器应该能够解析它。
我终于意识到它无法工作,因为我的编译器只有32位,导入库是64位。如果你是个傻瓜并且你不知道或不记得,那么你可以使用dumpbin
实用程序看到它:
$ 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)
到目前为止,这么好。但我浪费了一些时间,并希望避免重复这种经历。
虽然不是不正确,但LNK2019
错误消息并未引导您朝正确的方向前进。没有警告您正在尝试链接不同CPU架构的二进制文件。
请注意,当您指定X64体系结构时,会提示您指定X86二进制文件:
$ 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架构时,没有这样的精确警告:
$ 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 switch to link.exe
,当使用提示时,我的64位oci.lib
中找不到符号。
是否还有其他选项可以启用更多链接过程,呃,万无一失?
更新:根据Hans的回答,我在32位导入库上运行dumpbin
,名称如下所示:
$ 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导入库中的名称似乎未修饰:
OCIXmlDbFreeXmlCtx
OCIXmlDbInitXmlCtx
ORLRconNativeInt
ORLRvalNativeInt
OraCoreIsPhysicalRawFile
OraMemAlloc
Wikipedia regarding X86 calling conventions:
在Windows上下文中编译x64体系结构时(无论是否 使用Microsoft或非Microsoft工具),只有一个调用 约定 - 这里描述的那个,所以stdcall,thiscall,cdecl, fastcall等现在都是一样的。
现在对我有意义。唯一的调用约定,因此没有必要进行名称修改,因此在编译X86时,cdecl
没有前导下划线。
答案 0 :(得分:1)
我认为它只是抱怨在开始检查二进制兼容性之前缺少符号。这通常会首先发生,x64符号没有前导下划线,因为x64没有任何调用约定。除非您使用Microsoft导入库,否则它们根本不会装饰符号。
但我非常同意,首先获得兼容性错误会更有成效。不知道实施有多难。询问知道并且可以使其工作的人,向connect.microsoft.com发布功能请求