Запарка с компоновкой и вызовом функции. HELP!!!

Общие вопросы, не зависящие от языка реализации.

Модераторы: Duncon, Hawk, Romeo, Eugie

Ответить
Redcat
Сообщения: 19
Зарегистрирован: 08 дек 2005, 18:48
Откуда: Russia

13 дек 2005, 20:41

Народ, у меня следующая проблема. Помогите, кто сможет, оч. надо!

В коде для Win32 API я явно подключаю некоторую DLL, чтобы потом вызывать её функции по адресу (разрешение имени в адрес). В итоге у меня есть указатель на требуемую функцию lpDllFunc. Я вызываю её из метода своего класса, например:

SomeClass::SomeMethod(Arg1 arg1, &Arg2 arg2)
{
long RetVal = (lpDllFunc)(arg1, arg2);

// Затем я присваиваю значения закрытым полям класса _attr1 и
// _attr2

this->_attr1 = 0;
this->_attr2 = 0;
}

Проблема в том, что к моменту возврата из библиотечной функции lpDllFunc, содержимое памяти, где записан указатель на объект, для которого вызван этот метод, т.е this, меняется, и я теряю указатель на объект, и программа падает на строке this->_attr1 = 0.

Т.е, например, если до вызова lpDllFunc:
&this = 0x00aa00bb и this = 0x00db98bc,
то после:
&this = 0x00aa00bb а this=0x00ffcc00.

ДО

0x00aa00bb : 0x00db98bc 00000000 (сюда пишется RetVal)

ПОСЛЕ

0x00aa00bb : 0x00ffcc00 bff012ce (получил RetVal)

Меняется содержимое памяти по адресу &this. Причем эта функция меняет 4 байта по адресу &this и записывает возвращаемое значение в следующие 4 байта памяти.


А если я компоную эту библиотеку неявно, то прямой вызов функции по имени все делает корректно и она записывает возвращаемое значение в те же следущие 4 байта после 4-х байтов с указателем this, а память &this не портит.

ДО

0x00aa00bb : 0x00db98bc 00000000 (сюда пишется RetVal)

ПОСЛЕ

0x00aa00bb : 0x00db98bc bff012ce (получил RetVal)
Absurd
Сообщения: 1213
Зарегистрирован: 26 фев 2004, 13:24
Откуда: Pietari, Venäjä
Контактная информация:

14 дек 2005, 13:22

А какой формат вызова lpDllFunc? __cdecl или __stdcall?
2B OR NOT(2B) = FF
Redcat
Сообщения: 19
Зарегистрирован: 08 дек 2005, 18:48
Откуда: Russia

14 дек 2005, 18:14

Спасибо, проблема снята. Нужно было использовать квалификатор вызова __stdcall. :lol:
Ответить