LoadLibrary () не работает при вызове из плагина, но работает в тестовой программе - PullRequest
0 голосов
/ 20 мая 2019

Я работаю над плагином для Autodesk 3ds Max 2017. Согласно документации Max , плагин компилируется в VS 2017 с использованием набора инструментов VS 2015 против 10.0.10586.0 Windows SDK.

Когда плагин загружается 3ds Max, он, в свою очередь, программно загружает несколько библиотек DLL, используя LoadLibrary(). До недавнего времени это работало нормально на моей машине. Он также все еще работает нормально на машинах других разработчиков.

То, что происходит сейчас на моей машине, так это то, что LoadLibrary() дает сбой и возвращает нулевой дескриптор. Код ошибки 127, т. Е. Не удалось найти указанную процедуру.

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

Фактически, следующая программа, запущенная в Visual Studio 2017 (также использующая набор инструментов VS 2015 против Windows SDK 10.0.10586.0), может нормально загружать эту DLL:

#include <Windows.h>

int main(int argc, char* argv[])
{
    auto result = LoadLibrary(L"C:\\path\\to\\appleseed.dll");
}

Для дальнейшего изучения этой проблемы я обратился к GFlags , который является частью средств отладки для Windows 10.

Вот полный вывод отладчика, выдаваемый при вызове LoadLibrary(): https://gist.github.com/dictoon/b3f9f7cb52d2d81078965133d5035a03

Я полагаю (но я не уверен на 100%), что соответствующая ошибка этого вывода следующая:

5f4c:54bc @ 131346281 - LdrpReportError - ERROR: Locating export "StackWalkEx" for DLL "C:\Windows\SYSTEM32\dbgeng.dll" failed with status: 0xc0000139.
Exception thrown at 0x00007FFCC6A9EAA8 (ntdll.dll) in 3dsmax.exe: 0xC0000139: Entry Point Not Found.
5f4c:54bc @ 131346281 - LdrpGenericExceptionFilter - ERROR: Function LdrpSnapModule raised exception 0xc0000139
    Exception record: .exr 000000000223F030
    Context record: .cxr 000000000223EB40

dbgeng.dll, по-видимому, является отладчиком Visual Studio, поэтому я подумал, что, возможно, ошибка возникнет только тогда, когда 3ds Max будет запущен в Visual Studio с подключенным отладчиком, но это не так: DLL также не может загружаться, когда 3ds Max запущен самостоятельно.

Проверка C:\Windows\SYSTEM32\dbgeng.dll с помощью зависимостей показывает, что экспортирует символ StackWalkEx() :

Редактировать 1 : @RbMm отметил, что StackWalkEx() на самом деле не экспортируется dbgeng.dll, а dbghelp.dll, как показано на скриншоте ниже:

Dependencies screenshot showing that dbgeng.dll does export StackWalkEx

Редактировать 2 : С выпуском сборки DLL, которую я пытаюсь загрузить, все тоже отлично работает. Если посмотреть на выходные данные отладчика, мы не пытаемся загрузить dbgeng.dll или найти StackWalkEx().

Редактировать 3 : Похоже, что отладочная версия библиотеки, которую я пытаюсь загрузить , имеет зависимость от dbgeng.dll:

Library that fails to load depends on dbgeng.dll

Но небольшая тестовая DLL, написанная с нуля, не делает этого!

Edit 4 : Теперь я подозреваю, что в Boost 1.69 (от которого зависит DLL, которую я пытаюсь загрузить), к которому мы недавно переключились (с Boost 1.55), введена зависимость от dbgeng.dll через его библиотека Stacktrace, представленная в Boost 1.65.

1 Ответ

1 голос
/ 21 мая 2019

Проблема связана с более старой версией dbghelp.dll, которая поставляется с 3ds Max и конфликтует с более новой версией, с которой связана appleseed.dll во время отладочной сборки.

Вызов функции StackWalkEx, который не удалось, зависит от dbghelp.dll функция StackWalkEx

Решение состоит в том, чтобы деактивировать или заменить более старую несовместимую версию dbghelp.dll в корневом каталоге Max.

StackWalkEx является частью DbgHelp и используется системными службами.Возможно, оно было недавно обновлено во время обновления Windows, что вызвало критические изменения.

...