`
hulianwang2014
  • 浏览: 693626 次
文章分类
社区版块
存档分类
最新评论
  • bcworld: 排版成这样,一点看的欲望都没有了
    jfinal

教你用Windows API 写一个Thread类(不使用static哦)------(4)

 
阅读更多

这一篇文章中主要是讲解怎么写代码把以上3篇文章的理论用起来,写出一个能用的Thread类(只是模型)

我在第3篇中提到了,要想把类的成员函数做Thread函数,一定要在一个时候把this指针赋值给ecx,问题是在类的成员函数里面是不太可能做这种事情的,因为如果你要让fun成为线程函数,你就需要在别的函数里面初始化ecx,这样感觉有点多余。我用的最简单的一个方法是写一段机器代码,在这个机器代码里面完成所有的工作:初始化ecx,跳转到fun函数………至于那段机器代码怎么来的我想,我们用Vs调试的时候有个显示机器代码的选项,可以用这个看到吧,呵呵。不说了,下面直接放代码。

//core.h
#ifndef __ZX_CORE_H__
#define __ZX_CORE_H__
#include <windows.h>

#ifndef interface
#define interface struct
#endif

#ifndef implement
#define implement :public
#endif

const static unsigned char	g_thread_proc[]=
{
	//------------parameter-----------------
	0x8B,0x44,0x24,0x04,				// mov         eax,dword ptr [esp+10h] 
	0x50,						// push        eax  

	//-----------this pointer-------------
	0xB9,0x00,0x00,0x00,0x00,   			// mov 	      ecx,0x12FF5C 

	//-----------call back function-------------
	0xB8,0x00,0x00,0x00,0x00,   			// mov         eax,0 
	0xFF,0xD0,					// call        eax

	//return
	0xC2,0x10,0x00					// ret         10h  
};


#endif
//runnable.h

#ifndef	__ZX_RUNNABLE_H__
#define __ZX_RUNNABLE_H__

#include "core.h"


interface ZXRunnable
{
	virtual void run(void* lpParameter)= 0;
};



#endif


//thread.h
#ifndef __ZX_THREAD_H__
#define __ZX_THREAD_H__
#include "core.h"
#include "runnable.h"

class ZXThread
{
public:
	ZXThread();
	ZXThread(ZXRunnable* runnable);
	virtual ~ZXThread();

public:
	void Start();
	void Wait();
	void SetRunnable(ZXRunnable* runnable);
	ZXRunnable* GetRunnable();

private:
	ZXRunnable*	m_pRunnable;
	HANDLE	m_hThread;
	unsigned char m_thread_proc[sizeof(g_thread_proc)];
};



#endif


//thread.cpp
#include "thread.h"

ZXThread::ZXThread(): m_pRunnable(NULL), m_hThread(NULL)	{	}

ZXThread::ZXThread(ZXRunnable* runnable): m_pRunnable(runnable), m_hThread(NULL){}

ZXThread::~ZXThread()
{
	delete m_pRunnable;
}


void ZXThread::SetRunnable(ZXRunnable* runnable)
{
	m_pRunnable=	runnable;
}


ZXRunnable* ZXThread::GetRunnable()
{
	return(m_pRunnable);
}


void ZXThread::Start()
{
	CopyMemory(m_thread_proc, g_thread_proc, sizeof(g_thread_proc));
	*(int*)(&m_thread_proc[6])= (int)m_pRunnable;
	void (ZXRunnable::*func)(void* lpParameter)= &ZXRunnable::run;
	int addr;
	__asm
	{
		mov eax, func
		mov addr, eax
	}
	*(int*)(&m_thread_proc[11])= addr;
	m_hThread= ::CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)(void*)m_thread_proc, 
		NULL, 0, NULL);
}


void ZXThread::Wait()
{
	::WaitForSingleObject(m_hThread, INFINITE);
}


以下就是测试用例了哦:

#include <iostream>
#include "thread.h"
using namespace std;

class ZXRun implement ZXRunnable
{
public:
	virtual void run(void* lpParameter)
	{
		cout<<"Hello,World!"<<endl;
	}
};

int main()
{
	ZXThread boss(new ZXRun);
	boss.Start();
	boss.Wait();
}


注意,这个代码可能会崩溃,因为我们让数据当指令执行,因此需要关闭DEP,关闭DEP的方法参见网址:http://www.baidu.com/s?ie=utf-8&bs=VS%E5%85%B3%E9%97%ADDEP&f=8&rsv_bp=1&rsv_spt=3&wd=Visual+Studio%E5%85%B3%E9%97%ADDEP&inputT=2696

其步骤也比较简单:打开工程属性(不是解决方案属性哦)->Linker->Advanced->Data execution prevention(后面选择NO)。

至此,全部过程完成。

分享到:
评论

相关推荐

    基于SIP开发软件电话的一些资源(转自YOUTOO)

    而要成功编译ExoSIP,似乎许多人被难住了,直接在XP-sp2上,用VC6,虽然你使用了eXoSIP推荐的winsock2.h,但是会得到一个 sockaddr_storage结构不能识别的错误,因为vc6自带的开发库太古董了...

    侯捷- -深入浅出MFC

    产生一个Worker Thread 产生一个UI Thread 线程的结束 线程与同步控制 MFC多线程程序例程 第15章 定制一个AppWizard 到底Wizard是什么? Custom AppWizard的基本操作 剖析AppWizard Components Dialog Templates和...

    detour 2.1

    ---- (4) 用CreateRemoteThread在该进程上创建一个线程,传入前面分配的虚存的起始地址作为线程函数的地址,即可为一个已在运行的进程装入一个DLL。通过DllMain 即可在一个已在运行的进程中运行自己的代码。 二. ...

    C#浏览器编程,学习使用

    3) 例如,当用户用鼠标点击一个超链的起点时,控制程序就调用一个客户从所需文档所在的远地服务器上取回该文档,并调用解释程序向用户显示该文档 4) HTML 解释程序是必不可少的,而其他的解释程序则是可选的。 5) ...

    Java精华(免费版)

    设想一下,你有一个简单的程序,用来提示用户输入一个URL,然后通过这个URL去下载一个网页。如果用户输入的URL有错误,构建器就会抛出一个exception。既然这个exception是checked exception,你的程序就可以捕获它...

    Java测试题2答案

    定义一个类名为"MyClass.java"的类,并且该类可被一个工程中的所有类访问,那么该类的正确声明应为:CD A double a=1.0; A private class MyClass extends Object B class MyClass extends Object C ...

    Visual.C#.编程精彩百例

    实例41 线程Thread Relative Static跟踪与实现 实例42 线程池(ThreadPool)的应用 实例43 多线程互斥运行 实例44 多线程时钟应用程序 实例45 监视多线程 实例46 防止多线程应用程序死锁 实例47 文件同步操作...

    TaskManager

    利用业余时间,写了个貌似windows自带的任务管理器(私下认为其功能更甚windows自带的)。 封装了许多API接口成为类(一些源自网络,一些自己封装),方便C++使用。但是对整个代码的设计比较烂,打算在学完设计模式...

    Java邮件开发Fundamentals of the JavaMail API

    Fundamentals of the JavaMail API Presented by developerWorks, your source for great tutorials ibm.com/developerWorks Table of Contents If you're viewing this document online, you can click ...

    Tricks of the Windows video Game Programming---part1

    FreakOut................................................................Windows Programming Model 47 The Genesis of Windows ......................................................................48 ...

    深入浅出MFC【侯捷】

    深入浅出MFC(第二版) 目录 第0章 你一定要知道(导读) 这本书适合谁 你需要什么技术基础 你需要什么软硬件环境 让我们使用同一种语言 本书符号习惯 本书例程的取得 范例程序说明 与前版本之差异 如何联络作者 第...

    深入浅出MFC 2e

    产生一个Worker Thread 产生一个UI Thread 线程的结束 线程与同步控制 MFC多线程程序例程 第15章 定制一个AppWizard 到底Wizard是什么? Custom AppWizard的基本操作 剖析AppWizard Components Dialog Templates和...

    Java2核心技术卷I+卷2:基础知识(第8版) 代码

    Java 核心技术 卷1 Index Chapter 1: An Introduction to Java 1 Java As a Programming Platform 2 The Java “White Paper” Buzzwords...A Complete Example: Accessing the Windows Registry 975 Index 991

    VC驿站基础班无KEY高清C++教程下载地址

    ③、各种开源控件类的使用; ④、MFC与SDK API中同名函数问题。 5、VC中常用控件的用法讲解 ①、VC中常用控件的用法讲解见:http://www.cctry.com/thread-106-1-1.html ②、VS2008中新增控件的用法讲解。 6、...

    微软内部资料-SQL性能优化2

     Advanced Windows, 4th Edition, Jeffrey Richter, Microsoft Press Related Web Sites  http://ntperformance/ Memory Definitions Memory Definitions Before we look at how SQL Server uses and ...

    《Visual.C#.编程精彩百例》配套光盘.part2

    ” 实例7 组件化“Welcome”程序 实例8 网络上的“Hello World” 实例9 Ref、Out与Params描述符的应用 实例10 C#自动内存管理的应用 实例11 一个有趣栈类的实现 实例12 垃圾收集器管理与...

    《Visual.C#.编程精彩百例》配套光盘part1

    ” 实例7 组件化“Welcome”程序 实例8 网络上的“Hello World” 实例9 Ref、Out与Params描述符的应用 实例10 C#自动内存管理的应用 实例11 一个有趣栈类的实现 实例12 垃圾收集器管理与...

    【VS2010 C# 代码】实时监听鼠标位置

    //调用下一个钩子 [DllImport("user32.dll", CharSet = CharSet.Auto, CallingConvention = CallingConvention.StdCall)] public static extern int CallNextHookEx(int idHook, int nCode, IntPtr wParam, IntPtr ...

    Python Cookbook英文版

    4.24 File Locking Using a Cross-Platform API 4.25 Versioning Filenames 4.26 Module: Versioned Backups 5. Object-Oriented Programming 5.1 Overriding a Built-In Method 5.2 Getting All ...

    cuda检测工具 devicequery.exe

    CUDA Device Query (Runtime API) version (CUDART static linking) Detected 1 CUDA Capable device(s) Device 0: "GeForce GTX 650" CUDA Driver Version / Runtime Version 9.1 / 8.0 CUDA Capability Major...

Global site tag (gtag.js) - Google Analytics