Здравствуйте Нартов Андрей Евгеньевич, вы писали:
A>>уточните зачем это надо. НАЕ>например, сделать нить (CreateThread()) из нестатической member function
Ну, для этого можно обойтись и вызовом не статической функции из статической или глобальной, а вообще... я как то выпердривался с этим делом. Как сделать это на C++ я не раскопал. На Delpth это делается легко. На Плюсах пришлось выпендриваться с asm-ом.
Общая идея такова — записываем указатель на фунцию и на this экземпляра объекта в структуру.
И эмулируем вызов функции. Вот код:
// Структура для передачи указателя на функцию класса
struct CUniversalFuncPtr
{
void * pF; // Указатель на функцию класса
// Заметьте — это простой указатель на начало области
// кодом занимаемой кодом функции.
void * pThis; // Указатель на this экземпляр класса
};
// Подопытный кролик. :)
class CClass
{
public:
void f1(int i)
{
printf("i = %d, m_i = %d", i, m_i);
}
int m_i;
};
// Функция динамически вызывающаяя функцию любого класса.
// UniversalFuncPtr — унивирсальный указатель :))
// i — параметр передаваемый в вызываемую функцию.
void SomeCaller(CUniversalFuncPtr UniversalFuncPtr, int i)
{
__asm
{
// Эмулируем thiscall
mov ecx, UniversalFuncPtr.pThis;
mov eax, UniversalFuncPtr.pF;
push i ; // закладываем значение параметра
call eax // ecx->f1(i);
}
}
int main(int argc, char* argv[])
{
// Создаем переменную — подопытного кролика...
CClass c1;
// и инициализируем ее переменную-член...
c1.m_i = 123456;
// Поулучаем указатель на функцию некоторого класса.
// Совершенно неважно какой это класс, главное что функция
// должна быть описанна как:
// void FuncName(int);
typedef void ( CClass::*pmfnP)(int);
pmfnP pFunction = &CClass::f1;
CUniversalFuncPtr UniversalFuncPtr;
// Закладываем указатель на объекта (this)
UniversalFuncPtr.pThis = (void*)&c1;
// Закладываем указатель на функцию
__asm { mov eax, dword ptr pFunction }
__asm { mov UniversalFuncPtr.pF, eax }
// Приведенные выше операторы аналогичны конструкции:
// UniversalFuncPtr.pF = (void*)pFunction;
// но к сожалению такая конструкция вызывает сообщение об ошибке:
// error C2440: 'type cast' : cannot convert from
// 'void (__thiscall CClass::*)(int)' to 'void *'
// ...
SomeCaller(UniversalFuncPtr, 55555);
getchar();
return 0;
}
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.