Проблемы при вызове функции из DLL
Есть DLL, написанная на Borland С++ Builder'е и экспортирующая ряд функций. Есть клиентское приложение на MSVC2005.
DLL-ка загружается динамически (LoadLibrary). Все функции в DLL описаны как WINAPI (по крайней мере так сказано в документации, так как исходников DLL у меня нет).
Проблема заключается в том, что при вызове одной из функций (пока заметил только у одной) вылазит ошибка
Судя по ошибке проблема в calling conversion. Вот только ведь все остальные функции работают нормально, хотя (судя по документации) соглашение у них то же.
Перепробовал в описании все возможные соглашения - результат тот же.
Причем в той же клиентской программе, скомпиленной в Builder'е, вызов этой функции проходит нормально.
Кусок кода для примера
.................................................................................................
g_fPinpadDownloadKey = (int (WINAPI *)(char far*, int ,
char far*))GetProcAddress(g_hZt588Dll,
"PinPad_DownloadKey");
..................................................................................................
g_fPinpadDownloadKey(szDownloadKey, strlen(szDownloadKey), szRevData); // Вот здесь ошибка
Пока чего-то ничего в голову не идет. Может кто подскажет?
Заранее благодарен.
Поигрался чуть с отладчиком, и выяснил, что вызываемая функция при очистке стека сдвигает его указатель еще на 4 лишних байта. В Builder'е все работает также, только там в коде нет проверки на соотвествие esp до вызова функции и после.
Матеря разработчиков библиотеки, отлаживаю дальше. :)
Суть вопроса чуть изменилась.
В каких случаях функция, принимающая три параметра (два указателя и int - в общей сложности 12 байт) будет при завершении очищать из стека 16 байт? Т.е. вместо ret 0Ch ret 10h. Возможно ли вообще такое (при том, что остальные функции в Dll работают как положено) или за это стоит "благодарить" разработчиков DLL, которые забыли в документации (h-ки у меня нет, только документация) указать в еще один параметр функции?
Собственно проблема разрешилась путем добавления в прототип функции еще одного параметра int.
Может там внутри есть перегруженный вариант функции ("сокращенный"), который попал в документацию, а фактически вызывется "расширенный"?
PS: От сим стд кол и воняет, что функция сама чистит то кол-во параметров, которое по ее мнению должны были ей передать, а не то что было передано на самом деле.
<< Все функции в DLL описаны как WINAPI ... - не стоит всему верить на слово, видимо не все (возможно в исходнике где-то имеется переопределение WINAPI, а разработчики об этом умалчивают???).
Да такое сплошь и рядом в билдеровски-, дельфино- и старо микрософтовско-произведенных программах. Мда, теперь компайлеры стали осторожнее, не то что в наши времена :D. Разработчикам мало того что набить жбан, так теперь надо связываться и выснять за что же таки отвечает этот последний параметр. А то велик риск неприятностей. Кстати дока к какой версии либы? Подходит? Есть смысл пошукать постарше и поновее (как доки так и либы)
выравнивании на 64 бита (вместо int исп. __int64)
так всеж при выравнивании или при передаче __int64?
не стоит всему верить на слово, видимо не все (возможно в исходнике где-то имеется переопределение WINAPI
для одной функции-то? сомнительно
PS: От сим стд кол и воняет,
Поглядел бы я в этом случае на happy-cdecl-developer'а при сдаче продукта заказчику :)
Так я не на слово, я документации :D
видимо не все (возможно в исходнике где-то имеется переопределение WINAPI, а разработчики об этом умалчивают???).
Возможно, хотя проявляется это только в одной функции, да и при вызове ведет она себя "правильно" (как WINAPI).
[QUOTE=Phodopus]
Да такое сплошь и рядом в билдеровски-, дельфино- и старо микрософтовско-произведенных программах. Мда, теперь компайлеры стали осторожнее, не то что в наши времена . Разработчикам мало того что набить жбан, так теперь надо связываться и выснять за что же таки отвечает этот последний параметр. А то велик риск неприятностей. Кстати дока к какой версии либы? Подходит? Есть смысл пошукать постарше и поновее (как доки так и либы).
[/QUOTE]
Да вроде пока ведет себя с этим параметром как должна (передал 0). Действую по принципу "пока работает - не трогаю". :) Хотя безусловно новую версию библиотеки искать придется, так как этот вариант с параметром лишь временный (и при выходе новой версии библиотеки скорее всего даст о себе знать).