Как привести void (__thiscall C::* )(void) в void (__thiscall*)(void*) — как это сделать? ))))
Здравствуйте, f, Вы писали:
f>Как привести void (__thiscall C::* )(void) в void (__thiscall*)(void*) — как это сделать? ))))
Если нужно позарез, могу посоветовать только union_cast:
template <typename T1, typename T2>
class union_cast
{
public:
union
{
T1 T1Value;
T2 T2Value;
} U;
};
Тогда, имея объявленные следующим образом классы foo и bar:
class foo
{
public:
void some_foo_func()
{
std::cout << "foo..." << std::endl;
}
};
class bar
{
public:
void some_bar_func()
{
std::cout << "bar..." << std::endl;
}
};
получим следующее решение, позволяющее приводить указатели на some_foo_func в some_bar_func и наоборот:
foo Foo;
bar Bar;
union_cast<pfn_foo_func, pfn_bar_func> UCast;
UCast.U.T1Value = &foo::some_foo_func;
(Foo.*UCast.U.T1Value)(); // foo...
UCast.U.T2Value = &bar::some_bar_func;
(Bar.*UCast.U.T2Value)(); // bar...
Должен предупредить, что это грязный хак и это будет работать только для совместимых в
двоичном плане типов.
Здравствуйте, f, Вы писали:
f>Как привести void (__thiscall C::* )(void) в void (__thiscall*)(void*) — как это сделать? ))))
http://www.rsdn.ru/forum/cpp/753888.1.aspxАвтор: MaximE
Дата: 08.08.04
Здравствуйте, f, Вы писали:
f>Как привести void (__thiscall C::* )(void) в void (__thiscall*)(void*) — как это сделать? ))))
1. определить тип указателя на глобальную функцию-обёртку:
void __cdecl global_function(void* pThis, int arg1, int arg2)
{
printf("%s(%i,%i)\r\n", __FUNCSIG__, arg1, arg2);
std::cout << std::flush;
}
typedef void (__cdecl *global_function_ptr_t)(void*,int,int);
2. определить тип указателя на член-функцию подопытного класса:
class foo
{
public:
void __cdecl member_function(int arg1, int arg2)
{
printf("%s(%i,%i)\r\n", __FUNCSIG__, arg1, arg2);
std::cout << std::flush;
}
};
typedef void(__cdecl foo::*member_function_ptr_t)(int,int);
3. инстанцировать/определить (и инициализировать) переменные указателей:
void wmain(int arg_count, wchar_t** arg_list)
{
foo f, f2;
global_function_ptr_t pgf = global_function;
member_function_ptr_t pmf = &foo::member_function;
//...
4. кастить теперь уже куда хочу:
//...
global_function_ptr_t pgf2 = *(global_function_ptr_t*)(void**)&pmf;
global_function_ptr_t pgf3 = reinterpret_cast<global_function_ptr_t>(*(void**)&pmf);
//...
5. вызывать функцию, передав первым параметром указатель на желаемый объект (дабы посмотреть как-что):
//...
pgf2(&f, 3, -3);
pgf3(&f2, 4, -4);
//...
вообще, вариантов много, и все нелегальные :3
| весь листинг программы |
| #include "_headers.h"
///////////////////////////////////////////////////////////////////////////////////////////////////
void __cdecl global_function(void* pThis, int arg1, int arg2)
{
printf("%s(%i,%i)\r\n", __FUNCSIG__, arg1, arg2);
std::cout << std::flush;
}
typedef void (__cdecl *global_function_ptr_t)(void*,int,int);
/*******************************************************************/
struct foo
{
void __cdecl member_function(int arg1, int arg2)
{
printf("%s(%i,%i)\r\n", __FUNCSIG__, arg1, arg2);
std::cout << std::flush;
}
};
typedef void(__cdecl foo::*member_function_ptr_t)(int,int);
void wmain(int arg_count, wchar_t** arg_list)
{
foo f, f2;
global_function_ptr_t pgf = global_function;
member_function_ptr_t pmf = &foo::member_function;
pgf(0, 1, -1);
(f.*pmf)(2, -2);
std::cout << std::endl;
global_function_ptr_t pgf2 = *(global_function_ptr_t*)(void**)&pmf;
global_function_ptr_t pgf3 = reinterpret_cast<global_function_ptr_t>(*(void**)&pmf);
pgf2(&f, 3, -3);
pgf3(&f2, 4, -4);
std::cout << std::endl;
return;
}
|
| |