Код ошибки LoadLibrary() 127

У меня возникают проблемы с LoadLibrary() и возникают ошибки, которые не имеют для меня смысла:

   ::SetLastError(0);

   m_hDll = ::LoadLibrary(szName);

   if (m_hDll == NULL) // Failure to load the DLL.
   {
      DWORD err = GetLastError();
   }

Ошибка 127 ( "Указанная процедура не может быть найдена." ) Это не имеет никакого смысла для меня при вызове LoadLibrary(). Я не вызывал GetProcaddress ( ) все же.

DLL (и приложение) скомпилированы с помощью VS ++ 2005 SP1.

Что может быть не так?

Ответ 1

Давайте сделаем это шаг за шагом:

  • Сообщение об ошибке означает, что DLL была найдена, но требуемая функция отсутствует. (Джиттер прав.) Это означает, что у вас есть dll, в котором вы нуждаетесь, но не в правильной версии. (Davefiddes прав, хотя проблема может быть любой DLL, а не только для библиотеки времени выполнения Microsoft. И, по крайней мере, для крупных обновлений Microsoft предоставляет библиотекам времени исполнения разные имена, поэтому в этом случае это не будет проблемой.)

  • Это не имеет смысла, поскольку из загружаемой DLL функции не запрашивается никакая функция. (Адам прав.)

  • Поэтому ожидаемая функция отсутствовала в DLL, которая явно загружается командой LoadLibrary, но в зависимой dll, которая неявно загружается одновременно, потому что для первой dll требуется Это. (Zebrabox был близок.)

  • Зависимая dll - это dll, которая "статически" связана с явной загрузкой библиотеки через библиотеку импорта или .lib файл, включенную на этапе компоновщика явно загруженной dll. (Бьюсь об заклад, вы не знали, что "динамическая библиотека ссылок" может быть "статически связана". Ну, теперь вы это делаете.)

  • Если у вас несколько версий одной и той же библиотеки в разных папках, это также может быть проблемой пути поиска (как предлагает зебребокс). Порядок поиска по пути Dll - это сложный вопрос сам по себе: см. http://msdn.microsoft.com/en-us/library/ms682586(VS.85).aspx. Это зависит, в частности, от операционной системы. Самая безопасная ставка, где это практично, заключается в том, чтобы поместить все потенциальные проблемы DLL в ту же папку, что и ваш exe.

  • Зависимые dll могут также иметь свои собственные зависимые dll, что может затруднить эту проблему. Зависимости могут помочь, но если это не так, попробуйте файлmon. Последняя dll, которая успешно прочитала перед вашим сообщением об ошибке, является той, которая неверна.

Ответ 2

Средство Microsoft gflags всегда скажет вам, какая зависимость не загружается и почему.

Запустите gflags -i your_application.exe +sls. После этого выполните приложение под отладчиком, чтобы зафиксировать трассировки .

gflags является частью Инструменты отладки - вы можете проверить C:\Program Files (x86)\Windows Kits\10\Debuggers\x64, чтобы узнать, есть ли у вас уже это. Вы можете добавить этот каталог к ​​своему пути или просто выполнить gflags из этого каталога в cmd.exe.

Например, после запуска gflags поместите точку останова на вызов ::LoadLibrary(_T("foo")) и перейдите на него, ища ошибки загрузчика в окне вывода Visual Studio, например

4b00:396c @ 479194074 - LdrpSnapThunk - ERROR: Procedure "[email protected][email protected]@[email protected]" could not be located in DLL "bar.dll"
First-chance exception at 0x0000000077307EF8 (ntdll.dll) in your_application.exe: 0xC0000139: Entry Point Not Found.
4b00:396c @ 479194074 - LdrpGenericExceptionFilter - ERROR: Function LdrpSnapIAT raised exception 0xc0000139
    Exception record: .exr 0000000000129070
    Context record: .cxr 0000000000128B80
4b00:396c @ 479194074 - LdrpHandleOneOldFormatImportDescriptor - ERROR: Snapping the imports from DLL "C:\test\64Debug\foo.DLL" to DLL "C:\test\64Debug\bar.dll" failed with status 0xc0000139

Это означает, что во время загрузки foo.dll была изменена зависимость bar.dll и сбой импорта bar.dll.

Ошибка импорта зависимостей, так как процедура [email protected][email protected]@[email protected] отсутствовала - вы можете demangle, чтобы public: void __cdecl vis_DollarMap::SetObject(int,void * __ptr64) __ptr64.

Вероятно, у вас неправильная версия зависимости - возможно, вам нужно перестроить зависимость, чтобы обновить ее.


Запустите gflags -i your_application.exe -sls, чтобы отключить трассировку загрузчика.

Ответ 3

Ошибка messag означает, что имеется соответствующая DLL, но отсутствует требуемый экспорт. У вас есть правильная версия DLL?

Вы можете использовать dumpbin.exe, чтобы проверить, какие функции экспортирует ваша DLL и проверить правописание.

Ответ 4

Установите инструменты отладки и запустите gflags -i your_application.exe +sls. После этого запустите приложение под отладчиком, чтобы захватить следы загрузчика.

Ответ 5

У вас есть несоответствие между временем выполнения, используемым для вашего приложения и DLL?

Проблема, которая укусила меня с VS 2005 в прошлом, состоит в том, что одна часть построена как сборка Release, а другая - как сборка Debug. Они приводят к разным версиям библиотек времени выполнения Microsoft, которые несовместимы, поскольку вы можете загружать только один файл в данном процессе.

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

Ответ 6

Два догадки от меня
1. LoadLibrary вызывает DllMain указанной DLL (первый раз, когда вы пытаетесь подключиться к процессу). Длинный выстрел, но он есть?
2. LoadLibrary загрузит указанную DLL и все ее зависимости. Поэтому, если зависимый модуль DLL не может быть расположен в пути поиска, что приведет к сбою загрузки - вы можете использовать параметр depend.exe для проверки - доступный здесь

Ответ 7

Я получил тот же код ошибки после вызова LoadLibrary(). Наконец, найденный через зависимый ходок, что некоторые зависимости модуля (szName) отсутствовали.

Ответ 8

Я бы предложил использовать Dependency Walker, чтобы узнать, какой метод отсутствует или какие DLL файлы необходимы или отсутствуют.

Ответ 9

Хорошо, вот мое решение: у нас была сложная система зависимостей, и среди них было две библиотеки DLL с тем же именем (т.е. server.dll), но расположенные по разным путям.

Когда client.dll был загружен с LOAD_WITH_ALTERED_SEARCH_PATH, кажется, что окна не смогли определить, какой из server.dll должен использоваться в разрешении символов (конечно, оба server.dll были успешно загружены).

Решение было довольно простым: пусть загруженные библиотеки имеют уникальные имена, то есть server-1.dll и server-2.dll.