MS VC linker (link.exe): Почему нет предупреждения о несоответствии 32-битной архитектуры ЦП? - PullRequest
3 голосов
/ 29 октября 2011

(Обновление: согласно предложению Ганса, вот предложение по улучшению поведения 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, что означает неразрешенный внешний символ 'symbol', указанный в функции '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 не ведет вас прямо в правильном направлении. Нет никаких предупреждений о том, что вы пытаетесь связать двоичные файлы для разных архитектур ЦП.

Обратите внимание, что при указании архитектуры 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.

1 Ответ

1 голос
/ 29 октября 2011

Я думаю, что он просто жалуется на отсутствие символа перед тем, как приступит к проверке двоичной совместимости.Обычно это происходит в первую очередь, символы x64 не имеют начального подчеркивания, поскольку x64 не имеет соглашений о вызовах.Если вы не используете библиотеки импорта Microsoft, они вообще не украшают символы.

Но я очень согласен, что сначала получить ошибку совместимости было бы гораздо более продуктивно.Понятия не имею, как сложно это реализовать.Спросите ребят, которые знают и умеют так работать, опубликуйте запрос на функцию connect.microsoft.com

...