CN101692206A - 一种为静态回调函数添加动态参数的方法及相关实现 - Google Patents
一种为静态回调函数添加动态参数的方法及相关实现 Download PDFInfo
- Publication number
- CN101692206A CN101692206A CN200910091692A CN200910091692A CN101692206A CN 101692206 A CN101692206 A CN 101692206A CN 200910091692 A CN200910091692 A CN 200910091692A CN 200910091692 A CN200910091692 A CN 200910091692A CN 101692206 A CN101692206 A CN 101692206A
- Authority
- CN
- China
- Prior art keywords
- back function
- parameter
- call
- new
- call back
- Prior art date
- Legal status (The legal status is an assumption and is not a legal conclusion. Google has not performed a legal analysis and makes no representation as to the accuracy of the status listed.)
- Pending
Links
Landscapes
- Executing Machine-Instructions (AREA)
Abstract
本发明公开了一种为静态回调函数添加动态参数的方法及相关实现,用于解决无法为静态回调函数添加动态参数的技术缺陷;本发明在原始回调函数的参数列表中添加一个或多个参数,通过参数注入代码将新添的参数和新回调函数的地址压入堆栈,在调用新的回调函数时,将参数注入代码段地址作为回调函数的入口地址,操作系统会在调用时首先执行参数注入代码,然后在参数注入代码段执行完毕后将新的回调函数地址返回给调用函数,在新的回调函数内部可正常使用通过参数代码段注入的动态参数。本发明使得开发人员可自由的向静态回调函数中传递参数,大大提高了编程的灵活性。
Description
技术领域
本发明涉及软件开发技术领域,尤其涉及一种为静态回调函数添加动态参数的方法及相关实现。
背景技术
很多系统中通过静态回调函数来向外部通知系统内部的运算结果,或通过静态回调函数来在系统内部执行用户自定义的操作。在程序中,开发人员会经常定义和使用静态回调函数,在某些场景下,开发人员会希望向静态回调函数中传递动态的参数,但系统并没有为开发人员提供相应的方法。通常的做法是采用一些特殊的标识(id)映射方法,例如:在窗体的静态回调函数中,通常采用窗体句柄的唯一性建立映射关系,通过id映射时,取出映射关系的映射计算是需要消耗计算资源,而且映射关系一般采用全局变量或模块来实现,全局变量和模块会使得系统复杂度上升。
在C++语言中,通常实现计时器(timer)类的方法有3种:采用窗体建立timer函数,对timer函数进行封装从而实现timer类;采用一个线程独立计数来实现timer类;采用timer id映射的方法来实现timer类。上述实现方法的缺陷是,采用窗体方式需要创建窗体,有系统消耗;采用独立线程方式系统资源消耗更大,而且实现过程复杂;
在C++语言中,把窗体静态回调函数映射到动态的对象的方法(子类化窗体)有两种实现方案:一种是采用MAP映射的方法(微软MFC就是采用的该方法),该方法用一个map表保存窗体句柄和对象this指针的映射关系,在窗体事件函数中,凭借窗体句柄的唯一性取出映射的对象this指针;另一种是通过窗体的SetWindowLong(hWnd,GWL_USERDATA,(LONG)this)函数来保存窗体对应的对象this指针,窗体事件函数中再用::GetWindowLong(hWnd,GWL_USERDATA)取出this指针。上述方法的缺陷是:第一种方法中的采用map映射,需要辅助的map映射实现,效率会受到影响。第二种方法的效率影响不大,但是只要知道hWnd的值的就可以改写GWL_USERDATA数据,数据安全没有保证。
发明内容
有鉴于此,本发明的目的之一提供一种为静态回调函数添加动态参数的方法及相关实现,用于解决无法为静态回调函数添加动态参数的技术缺陷,为达到上述目的,本发明的技术方案是这样实现的:
一种为静态回调函数添加动态参数的方法,包括:
在原始回调函数的基础上定义新的回调函数,在新的回调函数中添加动态参数;
在回调函数使用者调用所述新的回调函数时,通过执行参数注入代码,在新的回调函数执行之前,将添加的动态参数压入到堆栈中,在新的回调函数执行时,从堆栈中获取所述添加的动态参数,将其作为有效参数进行使用。
进一步地,所述方法具体为:
步骤A1、在原始回调函数的基础上定义新的回调函数,在新的回调函数的参数列表中添加所述动态参数;
步骤A2、建立参数注入代码,在参数注入代码中通过汇编代码将添加的动态参数压入堆栈,并把新的回调函数的地址也压入堆栈;
步骤A3、将参数注入代码段地址作为系统调用新的回调函数的函数地址入口,在系统调用所述新的回调函数时,首先执行所述参数注入代码段,然后再执行所述新的回调函数。
进一步地,所述动态参数的个数为一个或多个。
基于上述方法,本发明还提出一种定时器类的实现方法,包括:
在原始定时器(timer)回调函数的基础上定义新的定时器回调函数,在新的定时器回调函数中添加当前类对象的指针(this);
在定时器回调函数使用者调用所述新的定时器回调函数时,通过执行参数注入代码,在所述新的定时器回调函数执行之前,将当前类对象的指针作为参数压入到堆栈中,在所述新的定时器回调函数执行时,从堆栈中获取所述当前类对象的指针,将其作为有效参数进行使用。
进一步地,所述定时器类的实现方法具体为:
步骤B1、在原始定时器回调函数的基础上定义新的定时器回调函数,在新的定时器回调函数的参数列表中添加所述当前类对象的指针;
步骤B2、建立参数注入代码,在参数注入代码中通过汇编代码将添加的当前类对象的指针作为参数压入堆栈,并把新的定时器回调函数的地址也压入堆栈;
步骤B3、将参数注入代码段地址作为系统调用新的定时器回调函数的函数地址入口,在系统调用所述新的定时器回调函数时,首先执行所述参数注入代码段,然后再执行所述新的定时器回调函数。
进一步地,步骤B1中,除在新的定时器回调函数的参数列表中添加当前类对象的指针外,还可添加其它动态参数,相应地,在步骤B2中,所述参数注入代码将当前类对象的指针及其它动态参数依次压入堆栈。
基于上述方法,本发明还提出一种窗体子类化的方法,包括:
在原始窗体事件回调函数的基础上定义新的窗体事件回调函数,在新的窗体事件回调函数中添加当前类对象的指针(this);
在窗体事件回调函数使用者调用窗体事件回调函数时,通过执行参数注入代码,在所述新的窗体事件回调函数执行之前,将当前类对象的指针(this)作为参数压入到堆栈中,在所述新的窗体事件回调函数执行时,从堆栈中获取所述当前类对象的指针,将其作为有效参数进行使用。
一步地,所述窗体子类化的方法具体为:
步骤C1、在原始窗体事件回调函数的基础上定义新的窗体事件回调函数,在新的窗体事件回调函数的参数列表中添加所述当前类对象的指针;
步骤C2、建立参数注入代码,在参数注入代码中通过汇编代码将添加的当前类对象的指针作为参数压入堆栈,并把新的窗体事件回调函数的地址也压入堆栈;
步骤C3、将参数注入代码段地址作为系统调用新的窗体事件回调函数的函数地址入口,在系统调用所述新的窗体事件回调函数时,首先执行所述参数注入代码段,然后再执行所述新的窗体事件回调函数。
进一步地,步骤C1中,除在新的窗体事件回调函数的参数列表中添加当前类对象的指针外,还可添加其它动态参数,相应地,在步骤C2中,所述参数注入代码将当前类对象的指针及其它动态参数依次压入堆栈。
本发明在原始回调函数的参数列表中添加一个或多个参数,通过参数注入代码将新添的参数和新回调函数的地址压入堆栈,在调用新的回调函数时,将参数注入代码段地址作为回调函数的入口地址,操作系统会在调用时首先执行参数注入代码,然后在参数注入代码段执行完毕后将新的回调函数地址返回给调用函数,在新的回调函数内部可正常使用通过参数代码段注入的动态参数。本发明使得开发人员可自由的向静态回调函数中传递参数,大大提高了编程的灵活性。
附图说明
图1为本发明实施例1的为静态回调函数添加动态参数的方法的流程图。
具体实施方式
本发明其基本原理是:在原始回调函数的基础上定义新的回调函数,在新的回调函数中添加动态参数,在回调函数使用者调用所述新的回调函数时,通过执行参数注入代码,在新的回调函数执行之前,将添加的动态参数压入到堆栈中,在新的回调函数执行时,从堆栈中获取所述添加的动态参数,将其作为有效参数进行使用。通过本发明,可在回调函数的调用者保持不变的情况下,向静态回调函数添加动态的参数。
为使本发明的目的、技术方案和优点更加清楚明白,以下举实施例并参照附图,对本发明进一步详细说明。
实施例1:
在采用本发明传递动态参数的方法之前,原始回调函数类型的定义为:
typedef DWORD(CALLBACK*MYPROC)(DWORD param1,DWORDparm2);
系统函数(回调函数的使用者)的定义为:
void DoPoc(__in_opt MYPROC lpFunction)
{
DWORD p1=2;
DWORD p2=3;
DWORD dwReuslt=lpFunction(p1,p2);
}
原始回调函数的定义为:
DWORD CALLBACK Proc(DWORD param1,DWORD parm2)
{
return param1+param2;
}
系统函数调用原始回调函数的方式为:
DoPoc(MYPROC(Proc));
本发明可在系统函数(回调函数的使用者)DoPoc保持不变的情况下,向回调函数灵活的传入动态参数。
如图1所示,基于上述原始回调函数的定义及使用的方法,本发明向静态回调函数传递动态参数的具体过程如下:
步骤101:建立新的静态回调函数,该回调函数的定义可与使用者申明的回调函数MYPROC不同,本发明在新的静态回调函数的参数列表中添加新的一个或多个动态参数,参数的类型不限,比如定义如下回调函数,较原始回调函数而言,新的回调函数多添加了参数DWORD param0。
DWORD CALLBACK Proc1(DWORD param0,DWORD param1,DWORDparm2)
{
Return param0+param1+param2;
}
需要注意的是,该实施例中,参数param0的位置与参数注入代码的处理逻辑有关,采用不同的汇编语言,param0的位置可能也不相同。
步骤102:建立参数注入代码段,该参数注入代码段的功能就是传入动态的参数param0,使得Proc1中的param0有效。
DWORD lUserData=2342345;//新添加的动态参数
LPVOID lpAdapterCode=NULL;//参数注入代码段存储空间地址
#include<PshPack1.h>
struct
{
//在eax寄存器中保存返回地址,相当于汇编语句pop eax
BYTE operationcode_0x58;
//把要添加的动态参数压入堆栈,相当于汇编语句push userdata
BYTE operationcode_0x68;
DWORD m_1UserData
//把返回地址压入堆栈,相当于汇编语句push eax
BYTE operationcode_0x50;
//把回调函数地址压入堆栈
BYTE operationcode_2_0x68;
LPVOID m_lpAddress;//回调函数地址
//执行m_lpAddress指示的回调函数并返回
BYTE operationcode_0xc3;
}AdapterCode=
{
0x58,
0x68,
lUserData,
0x50,
0x68,
&Proc1,
0xc3
};
#include<PopPack.h>
//建立上述参数注入代码段的代码存储空间
lpAdapterCode=VirtualAlloc(NULL,sizeof(AdapterCode),MEM_COMMIT,PAGE_EXECUTE_READWRITE);
//保存参数注入代码段
memcpy(lpAdapterCode,&AdapterCode,sizeof(AdapterCode));
//刷新指令缓存,让CPU重新加载新的指令
FlushInstructionCache(GetCurrentProcess(),lpAdapterCode,sizeof(AdapterCode));
步骤103:系统函数调用新的静态回调函数,在调用时将参数注入代码段地址,即lpAdapterCode指针指向的地址作为回调函数入口地址。
DoPoc(MYPROC(lpAdapterCode));
请注意,lpAdapterCode的位置本来应该为Proc1,但由于Proc1和Proc的的参数不同,因此此处不能直接Proc1传给系统DoPoc函数,本发明将参数注入代码段的地址转换为MYPROC类型的地址传给DoPoc。
步骤104:系统函数DoPoc代码执行时,先运行参数注入代码段,然后再执行新的静态回调函数。
在DoPoc执行时,会先执行lpAdapterCode指向的参数注入代码段,在执行完参数注入代码段后在实际调用新定义的静态回调函数,由于在参数代码段中已将新添加的动态参数入栈,所以在该静态回调函数执行时,新添加的动态参数就可作为有效的参数被使用。
在该实施例中,在DoPoc执行lpFunction(p1,p2)代码时,事实上相当于执行了代码Proc1(lUserData,p1,p2)。
本发明可保持系统申明的回调函数的定义不变、系统调用的方式不变,大大提高了编程的灵活性。
实施例2:Windows平台下C++语言定时器(timer)类的实现
本实施例的关键是采用实施例1中为静态回调函数添加动态参数的方法,保存当前类对象的this指针,使得在timer事件函数中直接获得当前类的this指针,这样,即可在timer事件函数中通过this指针调用对象中的方法。
在windows的开发文档(sdk)中定义了定时器设置函数SetTimer以及该定时器设置函数中用到的回调函数TIMERPROC:
WINUSERAPI UINT_PTR WINAPI SetTimer(
__in_opt HWND hWnd,__in UINT_PTR nIDEvent,
__in UINT uElapse,__in_opt TIMERPROC lpTimerFunc
);
typedef VOID(CALLBACK*TIMERPROC)(HWND,UINT,UINT_PTR,DWORD);
要想在当前类中实现timer功能,并在静态回调函数中调用当前类对象的方法,关键在于如何在回调函数中获得当前类对象的this指针,该实施例通过参数注入代码将this指针传入静态回调函数,具体过程如下:
步骤201:定义新的静态定时器回调函数,增加一个指针参数,用于传递this指针;
LRESULT CALLBACK StaticTimerProc(CTimerProc*pTimer,HWND hWnd,
UINT uMsg,UINT_PTR uEventID,DWORD dwTimeTick)
其中pTimer为本发明新添加的待注入动态参数;
步骤202:建立参数注入代码段;
#include<PshPack1.h>
struct
{
//在eax寄存器中保存返回地址,pop eax
BYTE opcode_0x58;
//把this指针压入堆栈,push this
BYTE opcode_0x68;
CTimerProc*m_pThis;
//把返回抵制压入堆栈,push eax
BYTE opcode_0x50;
//把新建的定时器回调函数地址压入堆栈
BYTE opcode_2_0x68;
LPVOID m_lpAddress;
//执行m_lpAddress指示的新建的定时器回调函数并返回
BYTE opcode_0xc3;
}AdapterCode=
{
0x58,
0x68,
this,
0x50,
0x68,
&StaticTimerProc,
0xc3
};
#include<PopPack.h>
//建立代码存储空间
m_lpAdapterCode=VirtualAlloc(NULL,sizeof(AdapterCode),MEM_COMMIT,PAGE_EXECUTE_READWRITE);
//保存代码
memcpy(m_lpAdapterCode,&AdapterCode,sizeof(AdapterCode));
FlushInstructionCache(GetCurrentProcess(),m_lpAdapterCode,sizeof(AdapterCode));
步骤203:系统建立定时器,在建立定时器的系统调用函数中,将参数注入代码段的地址转换为原始回调函数地址后作为参数传给系统调用函数;
UINT_PTR SetTimer(UINT uElapse)
{
return::SetTimer(NULL,NULL,uElapse,TIMERPROC(m_lpAdapterCode));
}
在系统设置定时器时,仍使用TIMERPROC类型方式进行调用,即将m_lpAdapterCode指向的参数注入代码段的地址转换为TIMERPROC的指针类型,其在调用过程中需要将参数从右到左依次入栈,然后进入执行m_lpAdapterCode代码段,继续将this指针入栈。这样就调用到了新定义的回调函数StaticTimerProc过程,并且把this指针传给了StaticTimerProc过程。
步骤204:系统触发timer事件,执行新建立的静态定时器回调函数StaticTimerProc,StaticTimerProc再调用this指针对象中的OnTimerProc过程,使得和类绑定的静态回调函数进入和对象绑定的动态函数过程。
实施例3:Windows平台下C++语言的窗体子类化的方法
本实施例的关键是采用实施例1中为静态回调函数中添加动态参数的方法保存为窗体事件回调函数添加当前类的this指针参数,使得在窗体事件函数中可直接获得当前类的this指针,然后调用this对象中的方法。
在windows的sdk中窗体事件回调函数的定义如下:
WNDPROC typedef LRESULT(CALLBACK*WNDPROC)(HWND,UINT,WPARAM,LPARAM);
要想窗体子类化,关键在于在WNDPROC定义的回调函数中获得当前对象的this指针,具体实现步骤如下:
步骤301:定义新的窗体事件回调函数;
static LRESULT CALLBACK StaticWindowProc(CWindowProc*pWnd,HWND hWnd,UINT uMsg,WPARAM wParam,LPARAM lParam);
与系统定义的窗体事件回调函数类型不同的是,新定义的回调函数中新添加了pWnd参数,该参数用于传入this指针。
步骤302:建立参数注入代码段;
#include<PshPack1.h>
struct
{
//在eax寄存器中保存返回地址,pop eax
BYTE opcode_0x58;
//把this指针压入堆栈,push this
BYTE opcode_0x68;
CWindowSubClass*m_pThis;
//把返回地址压入堆栈,push eax
BYTE opcode_0x50;
//把函数地址压入堆栈
BYTE opcode_2_0x68;
LPVOID m_lpAddress;
//执行m_lpAddress指示的新的窗体事件函数并返回
BYTE opcode_0xc3;
}AdapterCode=
{
0x58,
0x68,
this,
0x50,
0x68,
&StaticWindowProc,
0xc3
};
#include<PopPack.h>
m_lpAdapterCode=VirtualAlloc(NULL,sizeof(AdapterCode),MEM_COMMIT,PAGE_EXECUTE_READWRITE);
memcpy(m_lpAdapterCode,&AdapterCode,sizeof(AdapterCode));
FlushInstructionCache(GetCurrentProcess(),m_lpAdapterCode,sizeof(AdapterCode));
步骤303:替换并保存老的窗体事件回调函数,通过SetWindowLong设置新的窗体事件函数为当前窗体事件处理函数:
m_oldWWINDOWPROC=(WNDPROC)LongToPtr(GetWindowLong(hWnd,GWL_WNDPROC));
SetWindowLong(hWnd,GWL_WNDPROC,PtrToLong(m_lpAdapterCode));
系统通过SetWindowLong设置当前窗体的事件处理函数时,将m_lpAdapterCode指向的参数注入代码段的地址经类型转化后传入SetWindowLong,其在调用过程中需要将参数从右到左依次入栈,然后进入执行m_lpAdapterCode代码段,继续将this指针入栈。这样就调用到了新定义的回调函数StaticWindowProc过程,并且把this指针传给了StaticWindowProc。
步骤304:系统调用新建立的静态回调函数,执行新建立的静态定时器回调函数StaticWindowProc,StaticWindowProc再调用this指针对象中的WindowProc过程,使得和类绑定的静态回调函数进入和对象绑定的动态函数过程。
基于上述步骤,具体的实现代码如下:
class CWindowSubClass //窗体子类定义
{
private:
LPVOID m_lpAdapterCode;//参数注入代码段指针变量
private:
WNDPROC m_oldWWINDOWPROC;//用于保存老的窗体事件回调函数
private:
HWND m_hWnd;
public:
HWND GetHandle()
{
return m_hWnd;
}
public:
CWindowProc():m_lpAdapterCode(NULL),m_hWnd(NULL),
m_oldWWINDOWPROC(NULL)
{
}
~CWindowProc()
{
UnSubclass();
}
void UnSubclass()
{
if(IsWindow(m_hWnd)&&m_oldWWINDOWPROC!=NULL)
{
SetWindowLong(m_hWnd,
GWL_WNDPROC,PtrToLong(m_oldWWINDOWPROC));
m_oldWWINDOWPROC=NULL;
}
if(NULL!=m_lpAdapterCode)
{
VirtualFree(m_lpAdapterCode,0,MEM_RELEASE);
m_lpAdapterCode=NULL;
}
}
void Subclass(HWND hWnd)//窗体子类化函数
{
m_hWnd=hWnd;
#include<PshPack1.h>//参数注入代码开始
struct
{
//在eax寄存器中保存函数返回地址,pop eax
BYTE opcode_0x58;
//把this指针压入堆栈
//push this
BYTE opcode_0x68;
CWindowSubClass*m_pThis;
//把函数返回抵制压入堆栈,push eax
BYTE opcode_0x50;
//把函数地址压入堆栈
BYTE opcode_2_0x68;
LPVOID m_lpAddress;
//执行并返回
BYTE opcode_0xc3;
}AdapterCode=
{
0x58,
0x68,
this,
0x50,
0x68,
&StaticWindowProc,
0xc3
};
#include<PopPack.h>//参数注入代码段结束
//申请参数注入代码段存储空间
m_lpAdapterCode=VirtualAlloc(NULL,sizeof(AdapterCode),MEM_COMMIT,PAGE_EXECUTE_READWRITE);
//存储参数注入代码段
memcpy(m_lpAdapterCode,&AdapterCode,sizeof(AdapterCode));
//刷新指令缓存
FlushInstructionCache(GetCurrentProcess(),m_lpAdapterCode,sizeof(AdapterCode));
//保存老的窗体事件处理回调函数和
m_oldWWINDOWPROC=(WNDPROC)LongToPtr(GetWindowLong(hWnd,GWL_WNDPROC));
//设置新的窗体事件处理函数
SetWindowLong(hWnd,GWL_WNDPROC,PtrToLong(m_lpAdapterCode));
}
protected:
virtual LRESULT CALLBACK WindowProc(HWND hWnd,UINT uMsg,WPARAM wParam,LPARAM lParam)
{
return CallOldWindowProc(hWnd,uMsg,wParam,lParam);
}
LRESULT CALLBACK CallOldWindowProc(HWND hWnd,UINTuMsg,WPARAM wParam,LPARAM lParam)
{
if(NULL!=m_oldWWINDOWPROC)
return CallWindowProc(m_OldWNDPROC,hWnd,uMsg,wParam,lParam);
else
{
return-1;
}
}
private:
static
//新的窗体事件回调函数
LRESULT CALLBACK StaticWindowProc(CWindowProc*pWnd,HWND hWnd,UINT uMsg,WPARAM wParam,LPARAM lParam)
{
return pWnd->WindowProc(hWnd,uMsg,wParam,lParam);
}
};
以上所述,仅为本发明的较佳实施例而已,并非用于限定本发明的保护范围。
Claims (9)
1.一种为静态回调函数添加动态参数的方法,其特征在于,包括:
在原始回调函数的基础上定义新的回调函数,在新的回调函数中添加动态参数;
在回调函数使用者调用所述新的回调函数时,通过执行参数注入代码,在新的回调函数执行之前,将添加的动态参数压入到堆栈中,在新的回调函数执行时,从堆栈中获取所述添加的动态参数,将其作为有效参数进行使用。
2.根据权利要求1所述的方法,其特征在于,所述方法具体为:
A1、在原始回调函数的基础上定义新的回调函数,在新的回调函数的参数列表中添加所述动态参数;
A2、建立参数注入代码,在参数注入代码中通过汇编代码将添加的动态参数压入堆栈,并把新的回调函数的地址也压入堆栈;
A3、将参数注入代码段地址作为系统调用新的回调函数的函数地址入口,在系统调用所述新的回调函数时,首先执行所述参数注入代码段,然后再执行所述新的回调函数。
3.根据权利要求1所述的方法,其特征在于,所述动态参数的个数为一个或多个。
4.一种定时器类的实现方法,其特征在于,包括:
在原始定时器(timer)回调函数的基础上定义新的定时器回调函数,在新的定时器回调函数中添加当前类对象的指针(this);
在定时器回调函数使用者调用所述新的定时器回调函数时,通过执行参数注入代码,在所述新的定时器回调函数执行之前,将当前类对象的指针作为参数压入到堆栈中,在所述新的定时器回调函数执行时,从堆栈中获取所述当前类对象的指针,将其作为有效参数进行使用。
5.根据权利要求4所述的方法,其特征在于,所述方法具体为:
B1、在原始定时器回调函数的基础上定义新的定时器回调函数,在新的定时器回调函数的参数列表中添加所述当前类对象的指针;
B2、建立参数注入代码,在参数注入代码中通过汇编代码将添加的当前类对象的指针作为参数压入堆栈,并把新的定时器回调函数的地址也压入堆栈;
B3、将参数注入代码段地址作为系统调用新的定时器回调函数的函数地址入口,在系统调用所述新的定时器回调函数时,首先执行所述参数注入代码段,然后再执行所述新的定时器回调函数。
6.根据权利要求5所述的方法,其特征在于,步骤B1中,除在新的定时器回调函数的参数列表中添加当前类对象的指针外,还可添加其它动态参数,相应地,在步骤B2中,所述参数注入代码将当前类对象的指针及其它动态参数依次压入堆栈。
7.一种窗体子类化的方法,其特征在于,包括:
在原始窗体事件回调函数的基础上定义新的窗体事件回调函数,在新的窗体事件回调函数中添加当前类对象的指针(this);
在窗体事件回调函数使用者调用窗体事件回调函数时,通过执行参数注入代码,在所述新的窗体事件回调函数执行之前,将当前类对象的指针(this)作为参数压入到堆栈中,在所述新的窗体事件回调函数执行时,从堆栈中获取所述当前类对象的指针,将其作为有效参数进行使用。
8.根据权利要求7所述的方法,其特征在于,所述方法具体为:
C1、在原始窗体事件回调函数的基础上定义新的窗体事件回调函数,在新的窗体事件回调函数的参数列表中添加所述当前类对象的指针;
C2、建立参数注入代码,在参数注入代码中通过汇编代码将添加的当前类对象的指针作为参数压入堆栈,并把新的窗体事件回调函数的地址也压入堆栈;
C3、将参数注入代码段地址作为系统调用新的窗体事件回调函数的函数地址入口,在系统调用所述新的窗体事件回调函数时,首先执行所述参数注入代码段,然后再执行所述新的窗体事件回调函数。
9.根据权利要求8所述的方法,其特征在于,步骤C1中,除在新的窗体事件回调函数的参数列表中添加当前类对象的指针外,还可添加其它动态参数,相应地,在步骤C2中,所述参数注入代码将当前类对象的指针及其它动态参数依次压入堆栈。
Priority Applications (1)
Application Number | Priority Date | Filing Date | Title |
---|---|---|---|
CN200910091692A CN101692206A (zh) | 2009-08-28 | 2009-08-28 | 一种为静态回调函数添加动态参数的方法及相关实现 |
Applications Claiming Priority (1)
Application Number | Priority Date | Filing Date | Title |
---|---|---|---|
CN200910091692A CN101692206A (zh) | 2009-08-28 | 2009-08-28 | 一种为静态回调函数添加动态参数的方法及相关实现 |
Publications (1)
Publication Number | Publication Date |
---|---|
CN101692206A true CN101692206A (zh) | 2010-04-07 |
Family
ID=42080897
Family Applications (1)
Application Number | Title | Priority Date | Filing Date |
---|---|---|---|
CN200910091692A Pending CN101692206A (zh) | 2009-08-28 | 2009-08-28 | 一种为静态回调函数添加动态参数的方法及相关实现 |
Country Status (1)
Country | Link |
---|---|
CN (1) | CN101692206A (zh) |
Cited By (8)
Publication number | Priority date | Publication date | Assignee | Title |
---|---|---|---|---|
CN103135989A (zh) * | 2013-03-11 | 2013-06-05 | 北京经纬恒润科技有限公司 | 一种回调函数代码生成方法及装置 |
CN105094846A (zh) * | 2015-08-21 | 2015-11-25 | 浪潮(北京)电子信息产业有限公司 | 数据处理方法、系统及其事件驱动模型建立方法和系统 |
CN105700931A (zh) * | 2016-02-23 | 2016-06-22 | 北京蓝海讯通科技股份有限公司 | 一种代码注入方法及装置 |
CN105739967A (zh) * | 2016-01-19 | 2016-07-06 | 四川长虹电器股份有限公司 | 移动应用中js异步调用native的方法 |
CN105808256A (zh) * | 2016-03-08 | 2016-07-27 | 武汉斗鱼网络科技有限公司 | 一种构造合法堆栈返回值绕过函数调用检测的方法与系统 |
CN109918157A (zh) * | 2019-01-08 | 2019-06-21 | 北京航天飞行控制中心 | 操作处理方法和装置 |
CN111290950A (zh) * | 2020-01-22 | 2020-06-16 | 腾讯科技(深圳)有限公司 | 程序测试中测试点获取方法、装置、存储介质和设备 |
CN112035533A (zh) * | 2020-09-03 | 2020-12-04 | 中山大学 | 基于多参数量化策略回测的系统资源调度方法及装置 |
-
2009
- 2009-08-28 CN CN200910091692A patent/CN101692206A/zh active Pending
Cited By (11)
Publication number | Priority date | Publication date | Assignee | Title |
---|---|---|---|---|
CN103135989A (zh) * | 2013-03-11 | 2013-06-05 | 北京经纬恒润科技有限公司 | 一种回调函数代码生成方法及装置 |
CN103135989B (zh) * | 2013-03-11 | 2016-02-10 | 北京经纬恒润科技有限公司 | 一种回调函数代码生成方法及装置 |
CN105094846A (zh) * | 2015-08-21 | 2015-11-25 | 浪潮(北京)电子信息产业有限公司 | 数据处理方法、系统及其事件驱动模型建立方法和系统 |
CN105739967A (zh) * | 2016-01-19 | 2016-07-06 | 四川长虹电器股份有限公司 | 移动应用中js异步调用native的方法 |
CN105700931A (zh) * | 2016-02-23 | 2016-06-22 | 北京蓝海讯通科技股份有限公司 | 一种代码注入方法及装置 |
CN105808256A (zh) * | 2016-03-08 | 2016-07-27 | 武汉斗鱼网络科技有限公司 | 一种构造合法堆栈返回值绕过函数调用检测的方法与系统 |
CN109918157A (zh) * | 2019-01-08 | 2019-06-21 | 北京航天飞行控制中心 | 操作处理方法和装置 |
CN109918157B (zh) * | 2019-01-08 | 2022-05-10 | 北京航天飞行控制中心 | 操作处理方法和装置 |
CN111290950A (zh) * | 2020-01-22 | 2020-06-16 | 腾讯科技(深圳)有限公司 | 程序测试中测试点获取方法、装置、存储介质和设备 |
CN112035533A (zh) * | 2020-09-03 | 2020-12-04 | 中山大学 | 基于多参数量化策略回测的系统资源调度方法及装置 |
CN112035533B (zh) * | 2020-09-03 | 2022-07-12 | 中山大学 | 基于多参数量化策略回测的系统资源调度方法及装置 |
Similar Documents
Publication | Publication Date | Title |
---|---|---|
CN101692206A (zh) | 一种为静态回调函数添加动态参数的方法及相关实现 | |
US9003402B1 (en) | Method and system for injecting function calls into a virtual machine | |
US9164754B1 (en) | Runtime patching of native-code programs | |
CN100487658C (zh) | 一种检测内存访问越界的方法 | |
US8776033B2 (en) | Batch dispatch of java native interface calls | |
CN100568255C (zh) | 一种网页防挂马的方法 | |
US20040025148A1 (en) | Computer-implemented system and method for code generation | |
US10310827B2 (en) | Flow-based scoping | |
US20190324880A1 (en) | Memory health metrics | |
CN110569110B (zh) | 支持可交互的多虚拟机的区块链方法、电子设备 | |
CN100388195C (zh) | 一种64位视窗操作系统下获取函数参数的方法及系统 | |
CN103440457A (zh) | 基于进程模拟的二进制程序分析系统 | |
US20200026530A1 (en) | Type-constrained operations for plug-in types | |
US8578352B1 (en) | Optimizing object oriented programs using limited customization | |
KR20110099214A (ko) | 동결된 개체들을 위한 형식 설명자 관리 | |
CN103198244B (zh) | 保护动态链接库的方法 | |
CN111666112A (zh) | 平台插件的实现方法、装置、系统和计算机设备 | |
US6976254B2 (en) | Inter-method control transfer for execution engines with memory constraints | |
US7926048B2 (en) | Efficient call sequence restoration method | |
US10802855B2 (en) | Producing an internal representation of a type based on the type's source representation | |
CN111008153B (zh) | 一种单元测试方法及系统 | |
CN112631613A (zh) | 基于区块链平台的智能合约部署和调用方法及相关设备 | |
Caromel et al. | Robust exception handling in an asynchronous environment | |
US20130042235A1 (en) | Dynamic bootstrap literal processing within a managed runtime environment | |
KR101054596B1 (ko) | 자바카드용 마이그레이터를 이용한 메모리 절감 방법 |
Legal Events
Date | Code | Title | Description |
---|---|---|---|
C06 | Publication | ||
PB01 | Publication | ||
C10 | Entry into substantive examination | ||
SE01 | Entry into force of request for substantive examination | ||
C12 | Rejection of a patent application after its publication | ||
RJ01 | Rejection of invention patent application after publication |
Application publication date: 20100407 |