Помогите победить DLL
Здравствуйте! Я пишу на VC++ 6 и у меня возникла проблема с подключением длл.
С раньше основном работал с айпишными библиотеками, но там все делается на автомате и никаких особых проблем не возникало, а сейчас появилась необходимость расчитывать хэш-функцию файла используя библиотеку
put_hash.dll (
put_hash.h put_hash.lib)
При попытке подключить библиотеку статически, выдает сообщение «Заголовок .либ файла поврежден или не верен».
Тогда я попытался подключить функции динамически. Посмотрел пример из MSDN и начал:
typedef INT (*MYPROC)(LPTSTR);
typedef INT (*MYPROC2)(LPTSTR, LPTSTR, LPINT, LPINT);
HINSTANCE hDLL;
MYPROC ProcAdd;
MYPROC2 ProcAdd2;
lptstr pathname="d:\\test.htm";
lptstr hash;
hDLL=LoadLibrary("put_hash.dll");
if(hDLL!=NULL)
{
ProcAdd=(MYPROC)GetProcAddress(hDLL,"InitPUT_HASH");
(ProcAdd);
ProcAdd2=(MYPROC2)GetProcAddress(hDLL,"MakeHashFile");
(ProcAdd2)(pathname, hash, os_error, hash_error);
ProcAdd=(MYPROC)GetProcAddress(hDLL,"DonePUT_HASH");
(ProcAdd);
}
FreeLibrary(hDLL);
Из put_hash.h
/*
pathname - полное имя файла
hash - значение хеш функции пpеобpазованное в стpоку в шестнадцатеpичном
фоpмате
os_error - код ошибки ОС или 0
hash_error - код ошибки функции или 0
Возвpат 0 - ОК
#0 - когда hash_error или os_error #0
*/
int PASCAL CALLBACK _export MakeHashFile(
lptstr pathname,
lptstr hash,
lpint os_error,
lpint hash_error);
В этом случае у меня появилась ошибка “Unhandled exception” при вызове функции MakeHashFile. Когда я посмотрел дллку через быстрый просмотр, оказалось что GetProcAddress возвращает адрес совсем другой функции! (т.е. Entry Point у InitPUT_HASH 0x0000e82c, а у @__lockDebuggerData$gv 0x00003329. GetProcAddress(hDLL,”InitPUT_HASH”) возвращает 0x00883329!)
Помучавшись, я стал задавать адреса напрямую:
ProcAdd=(MYPROC)0x0088e82c;
ProcAdd2=(MYPROC2)0x008856d4;
В этом случае все проходит нормально, ошибок нет, но и результата работы тоже нет!
По идее функция должна записывать в hash высчитанную хэш-функцию файла.
Бьюсь уже неделю! Подскажите, что я неправильно делаю? Может библиотека битая?
Может у меня руки кривые?
Здравствуйте Vold, Вы писали:
V>Помогите победить DLL
V>Здравствуйте! Я пишу на VC++ 6 и у меня возникла проблема с подключением длл.
V>С раньше основном работал с айпишными библиотеками, но там все делается на автомате и никаких особых проблем не возникало, а сейчас появилась необходимость расчитывать хэш-функцию файла используя библиотеку put_hash.dll (put_hash.h put_hash.lib)
V>При попытке подключить библиотеку статически, выдает сообщение «Заголовок .либ файла поврежден или не верен».
V>Тогда я попытался подключить функции динамически. Посмотрел пример из MSDN и начал:
V>typedef INT (*MYPROC)(LPTSTR);
V>typedef INT (*MYPROC2)(LPTSTR, LPTSTR, LPINT, LPINT);
Судя по тому, что написано в put_hash.h, правильный прототип будет
typedef INT (CALLBACK *MYPROC)(LPSTR);
typedef INT (CALLBACK *MYPROC2)(LPSTR, LPSTR, LPINT, LPINT);
V>HINSTANCE hDLL;
V>MYPROC ProcAdd;
V>MYPROC2 ProcAdd2;
V>lptstr pathname="d:\\test.htm";
V>lptstr hash;
V> hDLL=LoadLibrary("put_hash.dll");
V> if(hDLL!=NULL)
V> {
V> ProcAdd=(MYPROC)GetProcAddress(hDLL,"InitPUT_HASH");
Строчка ниже не выглядит как вызов функции по указателю.
V> (ProcAdd);
Правильно будет
(*ProcAdd)(); // C style
ProcAdd(); // C++ style
(ProcAdd)(); // no style but works
V> ProcAdd2=(MYPROC2)GetProcAddress(hDLL,"MakeHashFile");
V> (ProcAdd2)(pathname, hash, os_error, hash_error);
V> ProcAdd=(MYPROC)GetProcAddress(hDLL,"DonePUT_HASH");
V> (ProcAdd);
V> }
V> FreeLibrary(hDLL);
V>
Здравствуйте Alex Fedotov, Вы писали:
AF>Судя по тому, что написано в put_hash.h, правильный прототип будет
AF>AF>typedef INT (CALLBACK *MYPROC)(LPSTR);
AF>typedef INT (CALLBACK *MYPROC2)(LPSTR, LPSTR, LPINT, LPINT);
AF>
Спасибо за подсказку! Так действительно правильно и функции хоть стали возвращать значения (возвращает 0, т.е. отсутствие ошибки), но основную задачу не выполняет
Все таки меня смущает разница ссылок на функции библиотеки (адрес который мне указывает дебагер и адрес который указан при быстром просмотре).
При вызове основной функции MakeHashFile она опять таки возвращает ноль, но внизу в окне сообщений дебага выдает сообщение "First-chance exception in hash.exe: (KERNEL32.DLL): 0xC0000005: Access Violation"
Спасибо за ссылку на статью, но из-за либ файла мне подходит только явное подключение. Пробовал программу DLL to LIB, писал .dif файл, но тоже ничего не получилось

Мне уже проще начальнику сказать что библиотека битая, уж больно я на ней много времени потерял
Здравствуйте Vold, Вы писали:
V>Спасибо за подсказку! Так действительно правильно и функции хоть стали возвращать значения (возвращает 0, т.е. отсутствие ошибки), но основную задачу не выполняет :(
Вот этот код работает на моей системе: в szHash заносится нечто, похожее на хэш файла.
int
_tmain(
int argc,
_TCHAR * argv[]
)
{
HINSTANCE hInstance = LoadLibrary(_T("put_hash.dll"));
if (hInstance == NULL)
return -1;
INT (CALLBACK * pInitPUT_HASH)();
VOID (CALLBACK * pDonePUT_HASH)();
INT (CALLBACK * pMakeHashFile)(PCSTR, PCSTR, PINT, PINT);
*(FARPROC *)&pInitPUT_HASH = GetProcAddress(hInstance, "InitPUT_HASH");
*(FARPROC *)&pDonePUT_HASH = GetProcAddress(hInstance, "DonePUT_HASH");
*(FARPROC *)&pMakeHashFile = GetProcAddress(hInstance, "MakeHashFile");
if (pInitPUT_HASH == NULL ||
pDonePUT_HASH == NULL ||
pMakeHashFile == NULL)
return -1
INT nRet, nOsErr, nHashErr;
CHAR szHash[MAX_PATH];
nRet = pInitPUT_HASH();
if (nRet != 0)
return nRet;
nRet = pMakeHashFile("D:\\dxdiag.txt", szHash, &nOsErr, &nHashErr);
pDonePUT_HASH();
return nRet;
}
V>Все таки меня смущает разница ссылок на функции библиотеки (адрес который мне указывает дебагер и адрес который указан при быстром просмотре).
Не верь быстрому просмотру, верь depends.exe. Адрес InitPUT_HASH — 0x00003329 относительно адреса загрузки DLL.
V>При вызове основной функции MakeHashFile она опять таки возвращает ноль, но внизу в окне сообщений дебага выдает сообщение "First-chance exception in hash.exe: (KERNEL32.DLL): 0xC0000005: Access Violation"
Это может быть признаком ошибки, а может и не быть.
В Вин98 тоже работает! Спасибо за советы! Жалко нельзя пиво в аттачменте отправить
Эх! Учить мне еще указатели — не переучить!