Проблема выделения памяти в DLL / C++
От: FlameStorm Земля ya.ru
Дата: 15.12.06 20:27
Оценка:
Из EXE вызывается функция в DLL, которая должна выделить память:

EXE:
typedef dword (__fastcall * GetModuleInfoFUNC)(MYTYPE **infobuf);

...
      MYTYPE *pinfo = NULL;

      GetModuleInfoFUNC GetModuleInfo =
         (GetModuleInfoFUNC)
         GetProcAddress(hdll, "GetModuleInfo");

      GetModuleInfo(&pinfo);
...


DLL:
...
MYAPI dword __fastcall GetModuleInfo(sModuleInfo **infobuf)
{
   *infobuf = (sModuleInfo *) GlobalAlloc(GPTR, sizeof(sModuleInfo)); // <<< ЗДЕСЬ ПРОБЛЕМА.
   **infobuf = modinfo; //(запись данных)
   return 0;
}

...


Проблема: ...exception at 0x000182c8 ...: 0xC0000005: Acc. viol. reading location 0x000182c8.

Функции из библиотеки вызываются нормально, но выделять память не хочет. Без разницы new, malloc, GlobalAlloc, LocalAlloc, HeapAlloc...
т.е. например

   *infobuf = (sModuleInfo *)-1;
   return 0;

функционирует.

Гуглил, смотрел статьи rsdn, но не нашёл то что искал.

18.12.06 13:27: Перенесено модератором из 'C/C++' — Кодт
Re: Проблема выделения памяти в DLL / C++
От: FlameStorm Земля ya.ru
Дата: 16.12.06 10:38
Оценка: 25 (1)
Упорные поиски ответа не дали, но нашёл сам методом догадок и экспериментов. Как это блин часто бывает.

Думаю это будет полезно здесь ответить на свой же вопрос.

Проблема заключалась в неверной подгрузке библиотеки:

hdll = LoadLibraryEx(FileName, NULL, DONT_RESOLVE_DLL_REFERENCES | LOAD_WITH_ALTERED_SEARCH_PATH)

Параметр DONT_RESOLVE_DLL_REFERENCES заставляет ОС загружать DLL в пространство процесса не вызывая точку входа DLL (с параметрами DLL_PROCESS_ATTACH и др.). Вроде бы хорошо — мне эти вызовы и не требовались.
Однако без этого невозможно вызывать из DLL внешние по отношению к ней функции, в т.ч. и выделения памяти, поэтому приходится:

hdll = LoadLibraryEx(FileName, NULL, LOAD_WITH_ALTERED_SEARCH_PATH)

Словил граблями в лоб. Бывает.
Re[2]: Проблема выделения памяти в DLL / C++
От: Аноним  
Дата: 18.12.06 11:01
Оценка:
FS>Параметр DONT_RESOLVE_DLL_REFERENCES заставляет ОС загружать DLL в пространство процесса не вызывая точку входа DLL (с параметрами DLL_PROCESS_ATTACH и др.). Вроде бы хорошо — мне эти вызовы и не требовались.
FS>Однако без этого невозможно вызывать из DLL внешние по отношению к ней функции, в т.ч. и выделения памяти, поэтому приходится:
Вообще DONT_RESOLVE_DLL_REFERENCES не резолвит таблицу импортов длл. Потому код дллки не сможет вызывать функции из других дллек. Т.е. попросту будет неюзабелен. Потому и DllMain вызывать нельзя. DONT_RESOLVE_DLL_REFERENCES используется например если нужно подгрузить ресурсную дллку не содержащую кода вообще (в некоторых случаях LOAD_LIBRARY_AS_DATAFILE не подходит для этогого)).


FS>Словил граблями в лоб. Бывает.

Ну так вы их себе очень заботливо подложили
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.