1. 程式人生 > >class中封裝回調函式 顯式傳遞this指標

class中封裝回調函式 顯式傳遞this指標

本文是用來湊數而已。因為本人實在討厭某個數字,巧的是,本人在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);
}