小男孩‘自慰网亚洲一区二区,亚洲一级在线播放毛片,亚洲中文字幕av每天更新,黄aⅴ永久免费无码,91成人午夜在线精品,色网站免费在线观看,亚洲欧洲wwwww在线观看

分享

自己實(shí)現(xiàn)IDispatch::Invoke方法

 quasiceo 2012-12-07

自己實(shí)現(xiàn)IDispatch::Invoke方法

分類: 技術(shù) 79人閱讀 評(píng)論(0) 收藏 舉報(bào)

因?yàn)榉N種原因,在只能得到一個(gè)IWebBrowser指針的情況下要接收javascript的window.external.XXX調(diào)用,

不得已自己實(shí)現(xiàn)了IDocHostUIHandler和IDispatch,為了使用方便,自己又需要實(shí)現(xiàn)類似MFC的DISPATCH_MAP:

首先用一個(gè)結(jié)構(gòu)體保存每個(gè)DISPATCH方法的ID,名字,this指針,函數(shù)地址,返回值類型,參數(shù)類型列表。這些都沒(méi)有什么難度。

然后在IDispatch::GetIDsOfNames里面通過(guò)方法名稱查找到方法ID返回。

最關(guān)鍵的是IDispatch::Invoke方法的實(shí)現(xiàn),怎么實(shí)現(xiàn)可變參數(shù)調(diào)用。

一、根據(jù)Invoke方法的參數(shù)與對(duì)應(yīng)的保存的結(jié)構(gòu)體信息對(duì)參數(shù)個(gè)數(shù),參數(shù)類型,返回值類型做安全校驗(yàn)。

二、因?yàn)楸4娴暮瘮?shù)地址指針,沒(méi)法確實(shí)函數(shù)原型(和MFC的DISPATCH_MAP一樣,參數(shù)個(gè)數(shù)、類型和返回值類型都是不定的),

只好想用匯編的call指令來(lái)直接調(diào)用,但參數(shù)入棧又是一個(gè)難題。

三、后來(lái)想了一個(gè)辦法,因?yàn)閂C++里面標(biāo)準(zhǔn)__thiscall調(diào)用約定,會(huì)按順序把參數(shù)壓入棧,把this指針寫入ECX寄存器,

所以我先根據(jù)參數(shù)類型把所有參數(shù)序列化到一個(gè)buffer里,得到所有參數(shù)總長(zhǎng)度size,然后在棧上分配長(zhǎng)度為size的空間,把buffer直接copy到分配好的棧里。然后直接用call指令調(diào)用函數(shù),這其中還有要注意的一些東西,一是原寄存器的保存,及調(diào)用后的還原。二是在分配??臻g后,由于修改了ESP,不能在后面的匯編指令里直接使用原來(lái)的臨時(shí)變量了,需要在分配??臻g前把這些需要用到的變量存到寄存器。三是保持棧平衡,寄存器入棧、出棧,分配的??臻g釋放等。

四、返回值的獲取,32位返回值會(huì)保存在EAX里,64位返回值分別在EDX和EAX保存高低32位,我的做法是直接用一個(gè)64位變量取出EDX和EAX值,然后根據(jù)函數(shù)實(shí)際的返回值類型取對(duì)應(yīng)的8/32/64位,因?yàn)樵趨R編里做這些判斷是很麻煩的,而這個(gè)取EDX和EAX的值對(duì)程序又不會(huì)有影響。

下面是關(guān)鍵代碼:

  1. _asm{  
  2.         mov ecx, pthis //把this指針壓入ECX  
  3.         push edx //把EDX入棧,保存EDX的原始值,為使用EDX做準(zhǔn)備  
  4.         mov edx, pStack //把參數(shù)buffer地址壓入EDX  
  5.         push esi //把ESI入棧,保存ESI的原始值,為使用ESI做準(zhǔn)備  
  6.         mov esi, pfn //函數(shù)地址壓入ESI  
  7.         mov ebx, lSize //參數(shù)buffer大小壓入EBX  
  8.         push ebp //開始分配??臻g 大小:lSize  
  9.         mov ebp,esp  
  10.         sub esp, ebx  
  11.         sub ebp, ebx  
  12.         push esi       //開始copy buffer到分配好的棧上  
  13.         push edi  
  14.         push ecx  
  15.         mov esi, edx    
  16.         mov edi, ebp  
  17.         mov ecx, ebx  
  18.         rep movsb  
  19.         add ebp, ebx  
  20.         pop ecx  
  21.         pop edi  
  22.         pop esi  
  23.   
  24.         call esi //調(diào)用函數(shù)  
  25.         add esp,ebx //釋放分配的??臻g  
  26.         mov esp,ebp   
  27.         pop ebp   
  28.         pop esi  
  29.         mov dword ptr [result],eax //獲取返回值  
  30.         lea eax,[result]  
  31.         add eax, 4  
  32.         mov dword ptr [eax],edx   
  33.         pop edx  
  34.     } 

    本站是提供個(gè)人知識(shí)管理的網(wǎng)絡(luò)存儲(chǔ)空間,所有內(nèi)容均由用戶發(fā)布,不代表本站觀點(diǎn)。請(qǐng)注意甄別內(nèi)容中的聯(lián)系方式、誘導(dǎo)購(gòu)買等信息,謹(jǐn)防詐騙。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請(qǐng)點(diǎn)擊一鍵舉報(bào)。
    轉(zhuǎn)藏 分享 獻(xiàn)花(0

    0條評(píng)論

    發(fā)表

    請(qǐng)遵守用戶 評(píng)論公約

    類似文章 更多