Поинтер из ДЛЛ
Модераторы: Hawk, Romeo, Absurd, DeeJayC, WinMain
Итак задача.... Имеецаа ДЛЛ написанная мною, не вдаваясь в подробности скажу, что подхватывать её надо на лету и никак иначе, так что LoadLibrary мне обеспечен. Из своей проги я вызываю методы своей ДЛЛки, и всё прекраснейшим образом работает но.... Стоит мне вызвать метод, который возвращает, или принимает поинтер.. любой поинтер как я получаю:
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.
Ошибку можно игнорить, но после этого начинаецца форменное загаживание стэка, вплоть до того, что дебагер в такие места приходит, что волосы встают дыбом причём не только на голове... Особенно весело когда дебагер прыгает на одну строчку назад.... Как вы понимаете так программа работать не может... Пробовал играться всякими __stdcall __fastcall (WINAPI CALLBACK PASCAL как выяснилось представляют собой __stdcall). Так как мне быть! Прикладываю код вызова метода
float *ff;
ff = NULL;
HMODULE DLL;
typedef void (WINAPI MESS)(float *);
MESS *Prep = NULL;
DLL = AfxLoadLibrary("MedusaDynamic.dll");
if(DLL != NULL)
{
Prep = (MESS *)GetProcAddress(DLL, "GetPointer");
if(Succ = (Prep != NULL))
(Prep)(ff);
На последней строчке и выскакивает ошибка....
Сам метод GetPointer объявлена так...
void WINAPI GetPointer(float *);
И реализована так:
void CMedusaDynamicApp::GetPointer(float *out)
{
out = ((CMedusaDynamicApp *)AfxGetApp())->InternalGetPointer();
}
Метод InternalGetPointer возвращает указатель на float который по любому существует, находится в области видимости и память выделена.... Что мне делать?
:?:
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.
Ошибку можно игнорить, но после этого начинаецца форменное загаживание стэка, вплоть до того, что дебагер в такие места приходит, что волосы встают дыбом причём не только на голове... Особенно весело когда дебагер прыгает на одну строчку назад.... Как вы понимаете так программа работать не может... Пробовал играться всякими __stdcall __fastcall (WINAPI CALLBACK PASCAL как выяснилось представляют собой __stdcall). Так как мне быть! Прикладываю код вызова метода
float *ff;
ff = NULL;
HMODULE DLL;
typedef void (WINAPI MESS)(float *);
MESS *Prep = NULL;
DLL = AfxLoadLibrary("MedusaDynamic.dll");
if(DLL != NULL)
{
Prep = (MESS *)GetProcAddress(DLL, "GetPointer");
if(Succ = (Prep != NULL))
(Prep)(ff);
На последней строчке и выскакивает ошибка....
Сам метод GetPointer объявлена так...
void WINAPI GetPointer(float *);
И реализована так:
void CMedusaDynamicApp::GetPointer(float *out)
{
out = ((CMedusaDynamicApp *)AfxGetApp())->InternalGetPointer();
}
Метод InternalGetPointer возвращает указатель на float который по любому существует, находится в области видимости и память выделена.... Что мне делать?
:?:
-
- Сообщения: 1228
- Зарегистрирован: 26 фев 2004, 13:24
- Откуда: Pietari, Venäjä
- Контактная информация:
Как это тебе удалось задекларировать GetPointer как WINAPI (aka __stdcall), а реализовать его как нестатический метод класса, который неявно имеет соглашение о вызове thiscall?
2B OR NOT(2B) = FF
Так и удалось! Камипилер это пропускает... Я уже разабрался. Проблема решается заменой объявления метода GetPointer в моей дллке.
Вместо
void WINAPI GetPointer(float *);
Надо
void __cdecl GetPointer(float *);
А вот ловить его надо как WINAPI и всё работает преотличнейшим образом! У меня даже начальник обрадовался. Эту работу я должен был сделать неделю назад.... =)))))
Вместо
void WINAPI GetPointer(float *);
Надо
void __cdecl GetPointer(float *);
А вот ловить его надо как WINAPI и всё работает преотличнейшим образом! У меня даже начальник обрадовался. Эту работу я должен был сделать неделю назад.... =)))))
Sulik, хочешь сказать, что тебе удалось объявить метод класса как отдельно-стоящую функцию??? Не смеши 

Теперь понял что вас интересует. Для любителей попридираться без повода, не оказывая реальной помощи, пишу отчётливее:
class CMedusaDynamicApp : public CWinApp
{
public:
void __cdecl GetPointer(float *);
}
Я думал будет достаточно только самой строки объявления метода. Вот и всё... Надеюсь я Вас исчо раз посмешил.... :lol:
ЗЫ господа, если можете помочь - помогайте. Не можете, то хотяб не флудите! =)))
class CMedusaDynamicApp : public CWinApp
{
public:
void __cdecl GetPointer(float *);
}
Я думал будет достаточно только самой строки объявления метода. Вот и всё... Надеюсь я Вас исчо раз посмешил.... :lol:
ЗЫ господа, если можете помочь - помогайте. Не можете, то хотяб не флудите! =)))
Извиняюсь за некоторую грубость. Утро, понедельник, что ещё человеку для грубости нужно? =))
-
- Сообщения: 1228
- Зарегистрирован: 26 фев 2004, 13:24
- Откуда: Pietari, Venäjä
- Контактная информация:
Не может он быть __cdecl. У нестатических методов класса есть один дополнительный неявный параметр - this.class CMedusaDynamicApp : public CWinApp
{
public:
void __cdecl GetPointer(float *);
}
Без этого параметра никак нельзя. Соглашение __cdecl передачу этого параметра никак не обеспечивает.
Скорей всего компилятор это пропускает, но игнорирует. Методы объектов всегда вызываются через thiscall.
Ну, если я увижу допустим своего сына, колющего микроскопом орехи, я сначала нафлудю, а потом отниму микроскоп.господа, если можете помочь - помогайте. Не можете, то хотяб не флудите! =)))
В данном случае возможность отнять тонкий инструмент я не имею. Остается флудить.
Там есть кнопочка - отредактировать сообщение. Попробуй ее.Извиняюсь за некоторую грубость. Утро, понедельник, что ещё человеку для грубости нужно? =))
2B OR NOT(2B) = FF
Пардон! Кнопошку я проигнорил! =)))) А по поводу cdecl я этого не знал... Но фишка в том, что ежели я его уберу, то работать перестаёт.. =((((
- Romeo
- Сообщения: 3126
- Зарегистрирован: 02 мар 2004, 17:25
- Откуда: Крым, Севастополь
- Контактная информация:
Господи, да не в cdecl проблема, а в идентификаторе static, который отсутствует...
Entites should not be multiplied beyond necessity @ William Occam
---
Для выделения С++ кода используйте конструкцию [ code=cpp ] Код [ /code ] (без пробелов)
---
Сообщение "Спасибо" малоинформативно. Благодарность правильнее высказать, воспользовавшись кнопкой "Reputation" в виде звёздочки, расположенной в левом нижнем углу рамки сообщения.
---
Для выделения С++ кода используйте конструкцию [ code=cpp ] Код [ /code ] (без пробелов)
---
Сообщение "Спасибо" малоинформативно. Благодарность правильнее высказать, воспользовавшись кнопкой "Reputation" в виде звёздочки, расположенной в левом нижнем углу рамки сообщения.
Надо попробовать. Это был мой первый опыт подхвата ДЛЛ на лету... Так что ваша инфа была для меня новой, пасиб шо рассказали. Как много нового узнаёшь! =)))))