将成员函数作为回调函数

在网上查了一些资料,做了一个Thunk模板,能够正确调用成员函数。但是在做取成员函数地址操作时比较麻烦,需要用到汇编。
//取成员函数地址
DWORD_PTR off = 0;
_asm
{
   mov eax, Class::MemFunc
   mov DWORD PTR [off], eax
}
每指定一个成员函数作为一个回调函数就要做如上操作。本想将Class和MemFunc作为两个参数定义一个宏包含汇编语言部分,
但不知道怎样编写汇编部分。如果有知道怎么编写的,希望能不吝赐教^_^

// Thunk 具体实现
#pragma pack( push, 1 )
struct Thunk_struct
{
 BYTE  op_movecx;  // as operation "mov" in asm
 DWORD_PTR val_ecx;
 BYTE  op_call;  // as operation "jmp" in asm
 DWORD_PTR val_address;
};
#pragma pack( pop )

template < class TCallback, class TClass >
class Thunk
{
public:
 TCallback MemFuncToCallback( TClass* pObject, DWORD_PTR pMemFuncAddress )
 {
  // 0xB9是“mov ecx, 数值”的机器码
  m_thunk.op_movecx = 0xB9;
  // 将对象指针pObject赋值给ecx
  m_thunk.val_ecx = (DWORD_PTR)pObject;
  // 0xE9是“jmp 相对地址”的机器码
  m_thunk.op_call = 0xE9;
  // 利用成员函数的具体地址pMemFuncAddress计算jmp的相对地址
  m_thunk.val_address = pMemFuncAddress - ((DWORD_PTR)(&m_thunk.val_address) + sizeof(DWORD_PTR));

  return (TCallback)&m_thunk;
 };

protected:
 Thunk_struct m_thunk;
};

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
如qsort 等函数需要函数指针才能回调 用此函数库可以将成员函数指针转为普通函数指针 测试代码如下 #include <stdio.h> #include <algorithm> #include <vector> #include <string> #include <iostream> #include <math.h> using cmpfunc = int(__cdecl*)(const void*, const void*); using DebugArrayFunc = void(__stdcall *)(std::string &out;); #include "thunk.h" class MySort { public: int Rule; MySort(int a):Rule(a){} // 回调函数 template<typename T> int __cdecl sort(const void* a, const void* b); }; class Test { public: std::vector<int> mm; void Sort(int (*comp)(const void *,const void *)) { return qsort(mm._Myfirst,mm.size(),sizeof(int),comp); } void Entry(DebugArrayFunc func) { std::string string; cmpfunc comp; TemplateThunk athunk; // 正序 comp = (cmpfunc)athunk.GetCall(&MySort;::sort<int>, &MySort;(0)); Sort(comp); func(string); std::cout << string << std::endl; // 逆序 comp = (cmpfunc)athunk.GetCall(&MySort;::sort<int>, &MySort;(1)); Sort(comp); func(string); std::cout << string << std::endl; } }; class CallBack { public: std::vector<int> *pthis; CallBack(std::vector<int> *ff):pthis(ff){} void __stdcall DebugArray(std::string &out;) { char buff[100]; char *aa = buff; for each (auto a in *pthis) { aa += sprintf(aa, "%d ", a); } out.assign(buff); } }; void main() { TemplateThunk athunk; Test tt; tt.mm = { 1, 3, 7, 8, 5, 6, 4, 2, 3, 10 }; tt.Entry(athunk.GetCall(&CallBack;::DebugArray,&CallBack;(&tt;.mm))); } template <typename T> int __cdecl MySort::sort(const void* a, const void* b) { return Rule ? *static_cast<const T*>(a)-*static_cast<const T*>(b) : *static_cast<const T*>(b)-*static_cast<const T*>(a); }
C++中,成员函数可以作为回调函数使用。这是因为成员函数与普通的函数不同,它们需要通过对象来调用。回调函数通常用来在特定的事件发生时执行某个操作。 当将成员函数作为回调函数使用时,需要使用类对象来调用它。首先,我们需要定义一个回调函数的接口,在接口中声明回调函数的参数和返回类型。然后,在类中定义一个成员函数,该成员函数回调函数的接口相匹配。 接下来,在程序中创建该类的对象,并将对象的成员函数作为回调函数传递给需要注册回调函数的地方,通常是在其他类或函数中。通过传递对象的地址或引用,其他类或函数就可以调用该对象的成员函数作为回调函数。 当事件触发时,那些注册了回调函数的地方就会调用相应的成员函数。由于成员函数是通过类对象调用的,它可以访问该类对象的成员变量和成员函数,以及其他相关的类信息。 通过使用成员函数作为回调函数,可以实现更灵活的程序设计。它可以方便地将代码逻辑封装在类中,并在需要的时候进行调用。此外,成员函数作为回调函数还可以在多线程编程中起到重要的作用,可以将任务委托给不同的线程进行执行。 总的来说,C++中可以使用成员函数作为回调函数,通过类对象来调用。这种用法可以帮助我们实现更灵活和模块化的程序设计,提高代码的重用性和可维护性。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值