LoadLibrary () код ошибки 127 - PullRequest
16 голосов
/ 27 июня 2009

У меня проблемы с 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.

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

Ответы [ 8 ]

26 голосов
/ 09 апреля 2010

Давайте рассмотрим шаг за шагом:

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

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

  3. Следовательно, ожидалось, что отсутствующая функция будет найдена не в dll, которая явно загружается командой LoadLibrary, а в зависимой dll, которая загружается в то же время неявно, поскольку первая dll требует Это. (Зебрабокс был близко.)

  4. Зависимая dll - это dll, которая «статически» связана с библиотекой, загружаемой явным образом, через библиотеку импорта или файл .lib, включенный в шаг компоновщика явно загруженной dll. (Держу пари, вы не знали, что «библиотека динамических ссылок» может быть «статически связана». Что ж, теперь вы понимаете.)

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

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

7 голосов
/ 11 мая 2016

Инструмент 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 "?SetObject@vis_DollarMap@@QEAAXHPEAX@Z" 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 завершился неудачей.

Не удалось импортировать зависимость, так как отсутствовала процедура ?SetObject@vis_DollarMap@@QEAAXHPEAX@Z - вы можете разобрать , что до public: void __cdecl vis_DollarMap::SetObject(int,void * __ptr64) __ptr64.

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


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

4 голосов
/ 19 августа 2011

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

4 голосов
/ 27 июня 2009

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

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

2 голосов
/ 27 июня 2009

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

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

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

1 голос
/ 27 июня 2009

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

0 голосов
/ 13 октября 2012

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

0 голосов
/ 18 марта 2011

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

...