visual-c++ - lib - unresolved external symbol__ imp__ sprintf



В чем разница между_imp и__imp? (1)

Я столкнулся с интересной ошибкой, когда пытался подключиться к MSVC-скомпилированной библиотеке, используя MinGW во время работы в Qt Creator. Компилятор жаловался на отсутствующий символ, который шел как _imp_FunctionName . Когда я понял, что это произошло из-за недостатка extern «C», и исправил его, я также запустил компилятор MSVC с помощью / FAcs, чтобы узнать, что представляют собой символы. Оказывается, это было __imp_FunctionName (это также то, как я читал на MSDN и довольно много сайтов блоггеров гуру).

Я полностью смущен тем, как линкер MinGW жалуется на символ, начинающийся с _imp , но он может найти его хорошо, хотя он начинается с __imp . Может ли глубокий маг-компилятор пролить свет на это? Я использовал Visual Studio 2010.


Это довольно прямое оформление идентификатора на работе. Префикс imp_ автоматически генерируется компилятором, он экспортирует указатель на функцию, который позволяет оптимизировать привязку к экспорту DLL. По языковым правилам imp_ имеет префикс ведущего подчеркивания, требуемого, поскольку он живет в глобальном пространстве имен и генерируется реализацией и в противном случае не отображается в исходном коде. Итак, вы получаете _imp_ .

Следующее, что происходит, - это то, что компилятор украшает идентификаторы, чтобы позволить компоновщику распознавать неверные совпадения. Довольно важно, потому что компилятор не может диагностировать несоответствия декларации между модулями и самостоятельно диагностировать их во время выполнения.

Во-первых, существует C ++ украшение, очень сложная схема, которая поддерживает перегрузки функций. Он генерирует довольно странные имена, обычно в том числе много? и @ символов с дополнительными символами для аргументов и возвращаемых типов, так что перегрузки недвусмысленны. Затем есть декорация для идентификаторов C, они основаны на вызывающем соглашении. Функция cdecl имеет одно ведущее подчеркивание, функция stdcall имеет лидирующий знак подчеркивания и конечный @n, который позволяет диагностировать несогласованные объявления аргументов, прежде чем они будут дисбаланс стека. Декорация C отсутствует в 64-битном коде, есть (благословенно) только одно соглашение о вызове.

Таким образом, вы получили ошибку компоновщика, потому что вы забыли указать ссылку C, линкеру было предложено сопоставить сильно украшенное имя C ++ с мягко оформленным именем C. Затем вы установили его с помощью extern "C" , теперь вы получили единственное добавленное подчеркивание для cdecl, превратив _imp_ в __imp_ .





mingw