利用Thunk讓C++成員函式變回調函式
Windows API經常需要回調函式,而在C++開發中面向物件當行其道,若能讓C++類的成員函式成為回撥函式,簡直就是大善!但是C++成員函式都隱含了一個this指標用於指向當前的物件。要實現回撥確實不容易。
我大約一年前就接觸到Thunk技術,甚至也看過利用Thunk實現將成員函式變成回撥函式的例子。但是我實在沒了解過C++彙編後的樣子,很容易鑽了牛角尖,看都看不懂,直接用他們的程式又不敢,畢竟出錯後不好處理。前端時間偶爾想起Thunk技術,對未懂技術老這樣懸著很可能影響自己的程式設計師生涯的,於是決心閉關參悟(沒辦法,資質差啊),終於弄明白了。那種感覺啊,就像誠信禮佛的人突然見到如來一樣,或者換了貼近自己的比喻:就像千年色鬼見到美女一樣的興奮。 我忍不住的模仿小說中的修真人士突悟大道後的感嘆:原來如此!
下面的分享一下我的收穫,基本上是出入門徑的寫給初學者的,大俠千萬要止步,小弟皮薄!
稍微研究了一下C++彙編後的程式碼,一般呼叫C++的成員函式之前,都是使用ECX暫存器儲存物件的指標,好在C++成員函式的呼叫約定__thiscall的引數壓棧順序和堆疊平衡的維護都是和回撥函式的呼叫約定__stdcall一樣,所以只需要構造彙編將物件指標儲存在ECX暫存器後JMP到成員函式的執行地址就可以了。先寫個C++結構拼湊這兩條彙編碼:
#pragma pack( push, 1 ) BOOL Init( DWORD_PTR proc, void* pThis ) void* GetCodeAddress() |
這個結構相當於兩條彙編語句:
mov ecx, pThis
jmp [偏移地址]
使用:
class CTestClass void memFun( int m, int n ) public: void Test() |
MemFunToStdCallThunk的Init方法接受成員函式指標和物件指標後就構造成2條彙編碼,當呼叫fun(1,3)時,
首先將引數3和1壓入堆疊,之後跳轉到m_thunk處,也就是那構造的2條彙編碼處,將物件指標儲存到ECX暫存器,之後跳轉到指定的成員函式處執行。一切OK了。
UnionCastType方法的程式碼如下:
template< typename TDst, typename TSrc > TDst UnionCastType( TSrc src ) { union { TDst uDst; TSrc uSrc; }uMedia; uMedia.uSrc = src; return uMedia.uDst; |
相關推薦
利用Thunk讓C++成員函式變回調函式
Windows API經常需要回調函式,而在C++開發中面向物件當行其道,若能讓C++類的成員函式成為回撥函式,簡直就是大善!但是C++成員函式都隱含了一個this指標用於指向當前的物件。要實現回撥確實不容易。 我大約一年前就接觸到Thunk技術,甚至也看過利用Thunk實現將成員函式變成回撥函式的例子。但
如何讓C++類的成員函式作為回撥函式
Element Implementation Argument-passing order Right to left. Argument-passing convention By value, unless a pointer or reference type is passed. Stack-ma
C++中 執行緒函式為靜態函式 及 類成員函式作為回撥函式
執行緒函式為靜態函式: 執行緒控制函式和是不是靜態函式沒關係,靜態函式是在構造中分配的地址空間,只有在析構時才釋放也就是全域性的東西,不管執行緒是否執行,靜態函式的地址是不變的,並不在執行緒堆疊中static只是起了一個裝飾的作用,所以二者並沒有必然的關係 執行緒也是一種
c++類的成員函式做回撥函式為啥要申明為static的
眾所周知,C++的類成員函式不能像普通函式那樣用於回撥,因為每個成員函式都需要有一個物件例項去呼叫它。 通常情況下,要實現成員函式作為回撥函式,一種常用的方法就是把該成員函式設計為靜態成員函式,但這樣做有一個缺點,就是會破壞類的結構性,因為靜態成員
在C++的類中使用類成員函式作為回撥函式
由於類有隱式的this指標,所以不能直接把類成員函式作為回撥函式使用。現用一例子來展示如何在類中使用類成員函式作為回撥函式。 此例子僅用於展示如何在類中使用類成員函式作為回撥函式 程式碼如下: #include "stdafx.h" #include
從C++類成員函式作為回撥函式說起
在網路訊息處理中經常要用到回撥機制。 例如處理非同步網路操作的前攝器設計模式(Proactor),(可以參考 《C++ 網路程式設計 卷2》中關於ACE Proactor模式實現 )。 非同步的 Web 伺服器將這樣來利用前攝器模式:首先讓 Web 伺服器向 OS 發出非同步
C++成員函式作為回撥函式的問題
1. 程式設計分兩類 一,應用程式設計和系統程式設計 系統程式設計就是編寫底層的庫, 應用程式設計就是利用已經編寫好的庫的介面來編寫某種具有某些功能的程式,即應用 所謂的庫,就是為了給應用提
C語言學習及應用筆記之七:C語言中的回撥函式及使用方式
我們在使用C語言實現相對複雜的軟體開發時,經常會碰到使用回撥函式的問題。但是回撥函式的理解和使用卻不是一件簡單的事,在本篇我們根據我們個人的理解和應用經驗對回撥函式做簡要的分析。 1、什麼是回撥函式 既然談到了回撥函式,首先我們就要搞清楚什麼是回撥函式。在討論回撥函式之前,我們需要說明另一個概念,
【cocos2d-x從c++到js】回撥函式1——按鍵回撥
回撥函式是介面互動和接入各種第三方SDK的關鍵所在,因為回撥函式的C++程式碼是不能自動生成的,一切的一切,都需要手寫完成。 比較不錯的是,Cocos2d-x引擎對於回撥函式提供了完整的包裝機制。我們所需要做的就是了解這個機制,並使用他。學習引擎自己的程式碼
c語言中的回撥函式
先來一段程式碼 #include<stdio.h> void show(void(*ptr)()){ (* ptr)(); } void show1(){ printf("hello world"); } void show2(){ printf("ni
C語言--結構體回撥函式示例
#include <stdio.h> struct component_provider { int component_id; const char *componen
將類的成員函式作為回撥函式(外一篇:友元函式)
問題的提出 我們已知道類具有封裝和資訊隱藏的特性。只有類的成員函式才能訪問類的私有成員,程式中的其他函式是無法訪問私有成員的。非成員函式可以訪問類中的公有成員,但是如果將資料成員都定義為公有的,這又破壞了隱藏的特性。另外,應該看到在某些情況下,特別是在對某些成員函式多次呼叫時,由於引數傳遞,型別檢查和安全性
C 函式指標 回撥函式
http://www.cnblogs.com/chenyuming507950417/archive/2012/01/02/2310114.html 今天討論下C/C++中的回撥函式。 &
如何使 類的成員函式作為回撥函式
如果試圖直接使用C++的成員函式作為回撥函式將發生錯誤,甚至編譯就不能通過。其錯誤是普通的C++成員函式都隱含了一個傳遞函式作為引數,亦即“this”指標,C++通過傳遞this指標給其成員函式從而實現程式函式可以訪問C++的資料成員。這也可以理解為什麼C++類的多個例項
【C語言】 使用回撥函式實現氣泡排序
實現功能:既能排序整型數,也可以排序字串 程式碼如下: #include <stdio.h> #include <string.h> int int_cmp(const v
如何實現類的成員函式作為回撥函式
回撥函式(Callback function)大量用於Windows的系統服務,通過它,程式設計師可以安裝裝置驅動程式和訊息過濾系統,以控制Windows的有效使用。許多程式設計師都發現,利用MFC或者其它的C++應用編寫回調函式是非常麻煩的,其根本原因是回撥函式是基於
利用觀察者模式來獲取執行緒中的資料或者回調函式
首先//抽象主題角色,watched:被觀察 public interface Watched { public void addWatcher(Watcher watcher); public void removeWatcher(Watcher wat
c#呼叫c++dll介面及回撥函式
在合作開發時,C#時常需要呼叫C++DLL,當傳遞引數時時常遇到問題,尤其是傳遞和返回字串是,現總結一下,分享給大家: VC++中主要字串型別為:LPSTR,LPCSTR, LPCTSTR, string, CString, LPCWSTR, LPWSTR等 但轉為C#
QT中類的成員函式作為回撥函式
這裡主要實現的功能:需要設計一個外掛,把外掛內的資料通過函式指標引數的方式傳遞到另外一個類中,顯示出來,使用回撥函式的方式 http://blog.csdn.net/ksn13/article/details/40538083,程式碼的邏輯和上述網站的第三種方法一樣
c++回撥函式/ROS回撥函式
以下均是個人在實際耕碼的過程中遇到的問題和整理的結果,可能會有不對的地方,望各位指正與交流 ------------------------------------------------------------------我會有喵的--------------------