Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > C/C++: Системное программирование и WinAPI > Динамический вызов ф-ций, что я делаю не так?


Автор: nic1986 1.7.2015, 13:25
Код

typedef int (*WINAPI dMessageBoxA)(HWND hWnd,LPCSTR lpText,LPCSTR lpCaption,UINT uType);

int _tmain(int argc, _TCHAR* argv[])
{
    HMODULE lib = LoadLibraryA("user32.dll");
    dMessageBoxA DM = (dMessageBoxA)GetProcAddress(lib, "MessageBoxA");
    DM(0, "", "", MB_OK);
    return 0;
}

студия мне рассказывает что соглашение о вызове не то(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.).
Но ведь в в самом winuser.h оно прописано как  __stdcall Что же не так?  smile  smile  

Автор: xvr 1.7.2015, 13:45
Цитата(nic1986 @  1.7.2015,  13:25 Найти цитируемый пост)
Но ведь в в самом winuser.h оно прописано как  __stdcall Что же не так?

MessageBox прописан, а не ваш typedef. Его вам надо прописать самим -
Код

typedef int (*WINAPI __stdcall dMessageBoxA)(HWND hWnd,LPCSTR lpText,LPCSTR lpCaption,UINT uType);

Автор: nic1986 1.7.2015, 17:10
xvr, Я вас не понял,у меня там и так соглашение о вызове __stdcall А проблема оказалась в багнутых настройках стека https://support.microsoft.com/en-us/kb/822039 Студия с каждой версией становиться все более корявой(((

Автор: xvr 2.7.2015, 12:33
Цитата(nic1986 @  1.7.2015,  17:10 Найти цитируемый пост)
Я вас не понял,у меня там и так соглашение о вызове __stdcall 

У вас вообще отсуствует указание о соглашении вызова, поэтому берется соглашение по умолчанию из настроек проекта. Не факт, что это __stdcall.

Хотя поправка: WINAPI уже определен как __stdcall, так что должно работать. Может WINAPI где то переопределили?

Цитата(nic1986 @  1.7.2015,  17:10 Найти цитируемый пост)
А проблема оказалась в багнутых настройках стека

И где у вас параметр размером более 64К (о чем говорится по приведенной вами ссылке)?

Автор: nic1986 2.7.2015, 14:14
WINAPI и есть по умолчанию у студии, как __stdcall.Факт в том что вышеупомянутая ошибка появляется когда в настройках проекта стоит RTCs, когда RTCu то все ОК. Возможно какая то цртшная заглушка на точке входе загаживает стек, или еще какое то непотребство творит.

Автор: xvr 3.7.2015, 14:40
Странно это. В студии конечно баги есть, но это уж очень большой баг, прямо дыра я бы сказал  smile 

Собрал ваш пример в VS2012. Получил warning на строке с typedef:

Цитата

c:\users\rakhvato\documents\projects\consoleapplication1\source.cpp(4): warning C4229: anachronism used : modifiers on data are ignored

Отсюда следует, что модификатор __stdcall (который в WINAPI) оно проигнорировало. Так что слом с RTCs вполне предсказуем.

Поменял typedef на 
Код

typedef int (WINAPI *dMessageBoxA)(HWND hWnd,LPCSTR lpText,LPCSTR lpCaption,UINT uType);

warning исчез

Запустил под дебагером c .RTCs - первый вариант сломался, второй нет. 

Так что ошибки лучше начинать искать со своей стороны, а не со стороны компилятора и IDE  smile 

Автор: nic1986 3.7.2015, 19:52
Не понял, что на что вы поменяли.
Код

typedef int(*__stdcall dMessageBoxA)(HWND hWnd, LPCSTR lpText, LPCSTR lpCaption, UINT uType);

int _tmain(int argc, _TCHAR* argv[])
{
    HMODULE lib = LoadLibraryA("user32.dll");
    dMessageBoxA DM = (dMessageBoxA)GetProcAddress(lib, "MessageBoxA");
    DM(0, "", "", MB_OK);
    return 0;
}

в релизе крашиться, судя по оллидебаг на RETN ф-ции точки входа,т.е. при срабатывание црт заглушки.

Автор: volatile 3.7.2015, 22:55
Цитата(nic1986 @  3.7.2015,  19:52 Найти цитируемый пост)
typedef int( * __stdcall * dMessageBoxA)(HWND hWnd, LPCSTR lpText, LPCSTR lpCaption, UINT uType);


Добавлено через 1 минуту и 55 секунд
nic1986, звездочку не там поставили.
смотрите как правильно ставить у xvr, 

Автор: nic1986 4.7.2015, 23:48
В мелких деталях вся суть, а так сразу и не заметишь  smile 

Автор: Alexeis 6.7.2015, 11:58
Мне вот интересно, звездочка перед __stdcall, что означала для компилятора? Он ее проигнорировал что ли?

Автор: GremlinProg 6.7.2015, 12:07
Цитата(Alexeis @  6.7.2015,  13:58 Найти цитируемый пост)
Мне вот интересно, звездочка перед __stdcall, что означала для компилятора? Он ее проигнорировал что ли? 

он ___stdcall после нее проигнорировал, т.к. обнаружил анахронизм:
Цитата

anachronism used : modifiers on data are ignored

Возможно, раньше можно было так писать smile

Добавлено через 3 минуты и 54 секунды
у меня, кстати, тоже первая мысль была, что это какая-то старая,доступная форма записи, из серии:
Код

const int x;
int const x;

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)