class中封裝回調函式 顯式傳遞this指標
阿新 • • 發佈:2019-02-13
本文是用來湊數而已。因為本人實在討厭某個數字,巧的是,本人在CSDN部落格上發表的文章數量正好是某個數字,於是加一篇。
1.最簡單的就是CreateThread
#if !defined(AFX_TTHREAD_H__7222F1CA_7289_41A3_98A3_431B6044B3AE__INCLUDED_) #define AFX_TTHREAD_H__7222F1CA_7289_41A3_98A3_431B6044B3AE__INCLUDED_ #if _MSC_VER > 1000 #pragma once #endif class TThread { public: void start(); TThread(); virtual ~TThread(); private: unsigned long _stdcall thread_test(); int m_private_data; }; #endif #include "stdafx.h" #include "TThread.h" #ifdef _DEBUG #undef THIS_FILE static char THIS_FILE[]=__FILE__; #define new DEBUG_NEW #endif TThread::TThread(){} TThread::~TThread(){} unsigned long _stdcall TThread::thread_test() { m_private_data=123; return 0; } void TThread::start() { typedef unsigned long (_stdcall TThread::*FUNC_POINT)(); FUNC_POINT FuncPoint=(FUNC_POINT)&TThread::thread_test; ::CreateThread(NULL,0,*(LPTHREAD_START_ROUTINE*)&FuncPoint,this,0,NULL); }
這樣,回撥函式就可以如同類的普通成員函式那樣,可以直接訪問類的資料和其他成員函式。
2.在DLL中回撥類的成員函式
假如有人寫了個DLL,這個DLL可能被外部程式,比如C,C++或者其他語言使用,那麼這個DLL該怎麼編寫?匯出一個類?那麼,C語言要想使用這個DLL恐怕會是一件麻煩的事情。
這種情況,DLL最好提供全域性函式式介面。
再多考慮一些。假如這個DLL需要呼叫上層應用怎麼辦?
答案是,只能使用回撥函式。
問題是,回撥函式一般都是全域性函式,C++程式中出現全域性函式總不是一件很雅觀的事情。所以,這裡提供一種稍微變通一點的辦法---顯式傳遞this指標。
假設DLL匯出了這麼一個函式,而且DLL還在此匯出函式中回調了類的某個成員函式,如下:
void dll_export_func(unsigned long func_addr,unsigned long class_this)
{
_asm push 1
_asm push 2
_asm mov ecx,class_this
_asm call func_addr
}
類的成員如何設計呢?很簡單,形式跟前面說得差不多,如下(類的標頭檔案就省略了):
TClass::TClass(){} TClass::~TClass(){} void TClass::init() { typedef void (TClass::*FUNC_POINT)(); FUNC_POINT FuncPoint=(FUNC_POINT)&TClass::dll_callback; ::dll_export_func(*(unsigned long*)&FuncPoint,(unsigned long)this); } void TClass::dll_callback(int a,int b) { printf("dll call my member func,pass param %d and %d\n",a,b); }