Из 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++' — Кодт
Упорные поиски ответа не дали, но нашёл сам методом догадок и экспериментов. Как это блин часто бывает.
Думаю это будет полезно здесь ответить на свой же вопрос.
Проблема заключалась в неверной подгрузке библиотеки:
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)
Словил граблями в лоб. Бывает.
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>Словил граблями в лоб. Бывает.
Ну так вы их себе очень заботливо подложили