PDA

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



Redcat
13.12.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
14.12.2005, 13:22
А какой формат вызова lpDllFunc? __cdecl или __stdcall?

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