Справочник функций

Ваш аккаунт

Войти через: 
Забыли пароль?
Регистрация
Информацию о новых материалах можно получать и без регистрации:

Почтовая рассылка

Подписчиков: -1
Последний выпуск: 19.06.2015

Проблемы при вызове функции из DLL

288
28 июля 2009 года
nikitozz
1.2K / / 09.03.2007
Доброго всем дня. Столкнулся вот с проблемой.
Есть DLL, написанная на Borland С++ Builder'е и экспортирующая ряд функций. Есть клиентское приложение на MSVC2005.
DLL-ка загружается динамически (LoadLibrary). Все функции в DLL описаны как WINAPI (по крайней мере так сказано в документации, так как исходников DLL у меня нет).
Проблема заключается в том, что при вызове одной из функций (пока заметил только у одной) вылазит ошибка
 
Код:
Run-Time Check Failure #0 - The value of ESP was not properly saved across a function call.  This is usually a result of calling a function declared with one calling convention with a function pointer declared with a different calling convention.

Судя по ошибке проблема в calling conversion. Вот только ведь все остальные функции работают нормально, хотя (судя по документации) соглашение у них то же.
Перепробовал в описании все возможные соглашения - результат тот же.
Причем в той же клиентской программе, скомпиленной в Builder'е, вызов этой функции проходит нормально.

Кусок кода для примера
 
Код:
int (WINAPI * g_fPinpadDownloadKey)(char far *pszKey, int iLen, char far *pszRevData);
.................................................................................................
g_fPinpadDownloadKey = (int (WINAPI *)(char far*, int ,
                                                 char far*))GetProcAddress(g_hZt588Dll,
                                                                           "PinPad_DownloadKey");
..................................................................................................
g_fPinpadDownloadKey(szDownloadKey, strlen(szDownloadKey), szRevData); // Вот здесь ошибка


Пока чего-то ничего в голову не идет. Может кто подскажет?
Заранее благодарен.
288
28 июля 2009 года
nikitozz
1.2K / / 09.03.2007
Небольшая поправка.
Поигрался чуть с отладчиком, и выяснил, что вызываемая функция при очистке стека сдвигает его указатель еще на 4 лишних байта. В Builder'е все работает также, только там в коде нет проверки на соотвествие esp до вызова функции и после.
Матеря разработчиков библиотеки, отлаживаю дальше. :)
288
28 июля 2009 года
nikitozz
1.2K / / 09.03.2007
Продолжаю свой монолог :)
Суть вопроса чуть изменилась.
В каких случаях функция, принимающая три параметра (два указателя и int - в общей сложности 12 байт) будет при завершении очищать из стека 16 байт? Т.е. вместо ret 0Ch ret 10h. Возможно ли вообще такое (при том, что остальные функции в Dll работают как положено) или за это стоит "благодарить" разработчиков DLL, которые забыли в документации (h-ки у меня нет, только документация) указать в еще один параметр функции?

Собственно проблема разрешилась путем добавления в прототип функции еще одного параметра int.
5
28 июля 2009 года
hardcase
4.5K / / 09.08.2005
Цитата: nikitozz
Собственно проблема разрешилась путем добавления в прототип функции еще одного параметра int.


Может там внутри есть перегруженный вариант функции ("сокращенный"), который попал в документацию, а фактически вызывется "расширенный"?

260
29 июля 2009 года
Ramon
1.1K / / 16.08.2003
Как вариант можно прожевать длл'ину дизассмом и посмотреть чего оно хочет "на самом деле". Действительно похоже, что в доке прозевали параметер.

PS: От сим стд кол и воняет, что функция сама чистит то кол-во параметров, которое по ее мнению должны были ей передать, а не то что было передано на самом деле.
9.0K
29 июля 2009 года
grag63
71 / / 23.01.2006
<< В каких случаях функция, принимающая ... - при выравнивании на 64 бита (вместо int исп. __int64).
<< Все функции в DLL описаны как WINAPI ... - не стоит всему верить на слово, видимо не все (возможно в исходнике где-то имеется переопределение WINAPI, а разработчики об этом умалчивают???).
14
29 июля 2009 года
Phodopus
3.3K / / 19.06.2008
Цитата: nikitozz
Возможно ли вообще такое (при том, что остальные функции в Dll работают как положено) или за это стоит "благодарить" разработчиков DLL, которые забыли в документации (h-ки у меня нет, только документация) указать в еще один параметр функции?


Да такое сплошь и рядом в билдеровски-, дельфино- и старо микрософтовско-произведенных программах. Мда, теперь компайлеры стали осторожнее, не то что в наши времена :D. Разработчикам мало того что набить жбан, так теперь надо связываться и выснять за что же таки отвечает этот последний параметр. А то велик риск неприятностей. Кстати дока к какой версии либы? Подходит? Есть смысл пошукать постарше и поновее (как доки так и либы)

Цитата:

выравнивании на 64 бита (вместо int исп. __int64)


так всеж при выравнивании или при передаче __int64?

Цитата:

не стоит всему верить на слово, видимо не все (возможно в исходнике где-то имеется переопределение WINAPI


для одной функции-то? сомнительно

Цитата:

PS: От сим стд кол и воняет,


Поглядел бы я в этом случае на happy-cdecl-developer'а при сдаче продукта заказчику :)

288
29 июля 2009 года
nikitozz
1.2K / / 09.03.2007
Цитата: grag63
не стоит всему верить на слово,


Так я не на слово, я документации :D

Цитата: grag63

видимо не все (возможно в исходнике где-то имеется переопределение WINAPI, а разработчики об этом умалчивают???).



Возможно, хотя проявляется это только в одной функции, да и при вызове ведет она себя "правильно" (как WINAPI).

[QUOTE=Phodopus]
Да такое сплошь и рядом в билдеровски-, дельфино- и старо микрософтовско-произведенных программах. Мда, теперь компайлеры стали осторожнее, не то что в наши времена . Разработчикам мало того что набить жбан, так теперь надо связываться и выснять за что же таки отвечает этот последний параметр. А то велик риск неприятностей. Кстати дока к какой версии либы? Подходит? Есть смысл пошукать постарше и поновее (как доки так и либы).
[/QUOTE]
Да вроде пока ведет себя с этим параметром как должна (передал 0). Действую по принципу "пока работает - не трогаю". :) Хотя безусловно новую версию библиотеки искать придется, так как этот вариант с параметром лишь временный (и при выходе новой версии библиотеки скорее всего даст о себе знать).

Реклама на сайте | Обмен ссылками | Ссылки | Экспорт (RSS) | Контакты
Добавить статью | Добавить исходник | Добавить хостинг-провайдера | Добавить сайт в каталог