Проблемы импорта DLL в Win32 (DllMain) - PullRequest
6 голосов
/ 28 мая 2010

У меня есть встроенная DLL, которая является плагином для другого приложения (которое я практически не контролирую).Все работает отлично, пока я не свяжусь с дополнительным файлом .lib (связывает мою DLL с другой DLL с именем ABQSMABasCoreUtils.dll).Этот файл содержит некоторые дополнительные API из родительского приложения, которые я хотел бы использовать.Я даже не написал ни одного кода для использования какой-либо экспортируемой функции, но только ссылки в этой новой DLL вызывают проблемы.В частности, я получаю следующую ошибку при попытке запустить программу:

Не удалось правильно инициализировать приложение (0xc0000025).Нажмите OK, чтобы закрыть приложение.

Я думаю, я где-то читал, что это обычно происходит из-за функции DllMain, возвращающей FALSE.Кроме того, в стандартный вывод записывается следующее сообщение:

ОШИБКА: попытка выделения памяти перед инициализацией компонента

Я почти на 100% уверен, что это сообщение об ошибке исходит отприложение и не является какой-то ошибкой Windows.

Рассматривая это немного больше (иначе говоря, вращаясь и переключая все переключатели, о которых я знаю), я связался с / MAP и обнаружил это в результирующем .mapfile:

 0001:000af220       ??3@YAXPEAX@Z              00000001800b0220 f   ABQSMABasCoreUtils_import:ABQSMABasCoreUtils.dll
 0001:000af226       ??2@YAPEAX_K@Z             00000001800b0226 f   ABQSMABasCoreUtils_import:ABQSMABasCoreUtils.dll
 0001:000af22c       ??_U@YAPEAX_K@Z            00000001800b022c f   ABQSMABasCoreUtils_import:ABQSMABasCoreUtils.dll
 0001:000af232       ??_V@YAXPEAX@Z             00000001800b0232 f   ABQSMABasCoreUtils_import:ABQSMABasCoreUtils.dll

Если я расшифрую эти имена, используя "undname", они приведут следующее (в том же порядке):

void __cdecl operator delete(void * __ptr64)
void * __ptr64 __cdecl operator new(unsigned __int64)
void * __ptr64 __cdecl operator new[](unsigned __int64)
void __cdecl operator delete[](void * __ptr64)

Я не уверен, что понимаю что-либо из ABQSMABasCoreUtils.dllможет существовать в этом файле .map или почему моя DLL даже пытается загрузить ABQSMABasCoreUtils.dll, если у меня нет кода, который ссылается на эту DLL.Может кто-нибудь помочь мне собрать эту информацию и выяснить, почему это не работает?Для чего это стоит, я подтвердил через «dumpbin», что родительское приложение импортирует ABQSMABasCoreUtils.dll, поэтому оно загружается несмотря ни на что.Я также попытался отложить загрузку этой DLL в мою DLL, но это не изменило результаты.

РЕДАКТИРОВАТЬ

Я дважды проверил, и все файлы являются 64-битными.

Ответы [ 4 ]

5 голосов
/ 12 ноября 2010

У меня точно такая же проблема. Это проблема API Abaqus, а не загрузки DLLS.

Я думаю, это потому, что API Abaqus переопределяет функции new и delete (как вы, похоже, заметили). Если вы вызываете new или delete в своей программе до инициализации Abaqus API, например, вызывая odb_initializeAPI();, тогда вы получаете

ОШИБКА: попытка выделения памяти перед инициализацией компонента

сообщение об ошибке и программа вылетает.

В моей программе вызов odb_initializeAPI(); до того, как первый new решил проблему.

2 голосов
/ 28 мая 2010

Ну, конечно, вы будете ссылаться на импорт этой библиотеки. Трудно написать программу на C ++ без использования оператора new или delete. Работа со сторонним программным обеспечением, которое думает, что ему необходимо переопределить CRT-версию этих операторов, достаточно сложна, невозможна, если она не позволит вам вызывать их, пока не придет время Оставьте все надежды или обратитесь за помощью к продавцу.

1 голос
/ 28 мая 2010

Одной из возможных причин ошибки при загрузке ABQSMABasCoreUtils.dll является то, что не удалось найти какой-либо модуль зависимости (включая DLL с отложенной загрузкой). Используйте Dependency Walker (см. http://www.dependencywalker.com/), чтобы проверить все зависимости ABQSMABasCoreUtils.dll.

У меня есть два предложения:

  1. Убедитесь, что вы можете загрузить ABQSMABasCoreUtils.dll в отношении LoadLibrary. Вам не нужно вызывать любую функцию из ABQSMABasCoreUtils.dll. Использование LoadLibrary Я не вижу в качестве конечного решения. Это всего лишь диагностический тест. С помощью теста вы можете убедиться, что у вас есть какие-то общие проблемы с загрузкой ABQSMABasCoreUtils.dll в вашей программе, или у вас есть какая-то проблема инициализации процесса.
  2. Если загрузка ABQSMABasCoreUtils.dll в отношении LoadLibrary не удалась, используйте функцию профилирования Dependency Walker для протокола всех вызовов, выполненных во время загрузки ABQSMABasCoreUtils.dll. Другим способом было бы использование Process Monitor (см. http://technet.microsoft.com/en-us/sysinternals/bb896645.aspx) для отслеживания того, какие операции с файлами и реестром будут выполняться во время загрузки ABQSMABasCoreUtils.dll.

Если LoadLibrary не удалось, значит, у вас действительно проблема с инициализацией DLL. Обычно проблема существует, если DLL внутри DllMain пытается использовать функцию из другой DLL, которая еще не инициализирована (еще не возвращается из DllMain). Прежде чем приступать к диагностике этой проблемы, мы должны попытаться исключить более простые проблемы с LoadLibrary.

0 голосов
/ 28 мая 2010

ABQSMABasCoreUtils.dll выглядит так, как будто он импортирует 64-битные функции. Ваш dll тоже 64-битный? Если нет, то это проблема - вы не можете смешивать библиотеки DLL, скомпилированные для разных архитектур, в одном процессе.

...