MS VC linker (link.exe): Почему нет предупреждения о несоответствии 32-битной архитектуры ЦП?
(Обновление: согласно предложению Ганса, вотпредложение улучшитьlink.exe
поведение, и вы можете проголосовать за него, если у вас есть аккаунт там.)
Хорошо, я дура. В январе я установил 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
, что значитнеразрешенный внешний символ «символ», указанный в функции «функция», Символ в вопросе (_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
сообщение об ошибке не ведет вас прямо в правильном направлении. Нет никаких предупреждений о том, что вы пытаетесь связать двоичные файлы для разных архитектур ЦП.
Обратите внимание, что когда вы указываете архитектуру 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 переключиться наlink.exe
, который при использовании намекает на то, что в моем 64-битном не найдено никаких символовoci.lib
.
Есть ли другие варианты, которые вы можете включить, чтобы сделать процесс связывания более надежным?
Обновить: Согласно ответу Ганса, я побежалdumpbin
в 32-битной библиотеке импорта, и имена выглядят следующим образом:
$ 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
Википедия о соглашениях о вызовах X86:
При компиляции для архитектуры x64 в контексте Windows (с использованием инструментов Microsoft или сторонних разработчиков) существует только одно соглашение о вызовах - описанное здесь, так что теперь все stdcall, thiscall, cdecl, fastcall и т. Д. Едины. и то же самое.
Также актуальностатья об искажении имени.
Имеет смысл для меня сейчас. Одно-единственное соглашение о вызовах, следовательно, нет необходимости в искажении имени, следовательно, не должно быть подчеркивания в соответствии сcdecl
при компиляции для X86.