void testfunc(void *param)
{
printf("\n\tcall global function %s\n", param);
} void *GetClassFuncAddr(...)
{
DWORD address; __asm
{
lea eax,address
mov edx, [ebp + 8]
mov [eax], edx
} return (void *)address;
} void *callfunc(void *pfn, void *pthis, void *param)
{
if (pthis != NULL)
{
unsigned long dwThis = (unsigned long)pthis; typedef void* (__fastcall *memfunc)(void *,int, void*);//__fastcall调用方式会先传递两个DWORD参数(ecx与edx)
//typedef void* (__thiscall *memfunc)(void *, void*);//__thiscall调用方式传递ecx /*typedef void* (__stdcall *memfunc)(void *);//__stdcall调用方式,此方式得准备this指针
__asm mov ecx, dwThis;
*/
return reinterpret_cast<memfunc>(pfn)(pthis, 0, param);
}
else
{
typedef void *(*normalfunc)(void*);
return reinterpret_cast<normalfunc>(pfn)(param);
}
} class CTest
{
public:
void SimpleFunc(char *str)
{
printf("\n\tcall member function %s\n", str);
} void SimpleCall(char *p)
{
callfunc(GetClassFuncAddr(&CTest::SimpleFunc), this, (void*)p);
}
}; int _tmain(int argc, _TCHAR* argv[])
{
CTest *pthis = new CTest();
char *str = "test str"; void *addr = GetClassFuncAddr(&CTest::SimpleCall);
callfunc(addr, pthis, (void*)str); callfunc(&testfunc, NULL, (void*)str);
return 0;
}

补充一点的:以上都是建立在被呼叫函数的格式为

void *func(void*);

另外,对于类的虚函数,此方法不适用,因为在调用虚函数时,需要先确定类的虚函数表,在此我没做过多分析

照目前这种情况对于我在写线程类上,感觉是够用了 ;)

具体格式看实际操作而定

如果我说的哪点不正确,请告知我 ;)

C++调用全局函数与类成员函数的更多相关文章

  1. C++中 线程函数为静态函数 及 类成员函数作为回调函数

    线程函数为静态函数: 线程控制函数和是不是静态函数没关系,静态函数是在构造中分配的地址空间,只有在析构时才释放也就是全局的东西,不管线程是否运行,静态函数的地址是不变的,并不在线程堆栈中static只 ...

  2. C/C++ 类成员函数指针 类成员数据指针

    普通函数指针:  "return_type (*ptr_name)(para_types) " 类成员函数指针: "return_type (class_name::*p ...

  3. 类成员函数指针的特殊之处(成员函数指针不是指针,内含一个结构体,需要存储更多的信息才能知道自己是否virtual函数)

    下面讨论的都是类的非静态成员函数. 类成员函数指针的声明及调用: 1 2 3 4 5 6 7 //pr是指向Base类里的非静态成员函数的指针 //其行参为(int, int),返回值为void vo ...

  4. 深入理解类成员函数的调用规则(理解成员函数的内存为什么不会反映在sizeof运算符上、类的静态绑定与动态绑定、虚函数表)

    本文转载自:http://blog.51cto.com/9291927/2148695 总结: 一.成员函数的内存为什么不会反映在sizeof运算符上?             成员函数可以被看作是类 ...

  5. 理解ATL中的一些汇编代码(通过Thunk技术来调用类成员函数)

    我们知道ATL(活动模板库)是一套很小巧高效的COM开发库,它本身的核心文件其实没几个,COM相关的(主要是atlbase.h, atlcom.h),另外还有一个窗口相关的(atlwin.h), 所以 ...

  6. 直接调用类成员函数地址(用汇编取类成员函数的地址,各VS版本还有所不同)

    在C++中,成员函数的指针是个比较特殊的东西.对普通的函数指针来说,可以视为一个地址,在需要的时候可以任意转换并直接调用.但对成员函数来说,常规类型转换是通不过编译的,调用的时候也必须采用特殊的语法. ...

  7. c++空指针调用类成员函数

    最近在看C++动态绑定问题时(理解静态绑定时)发现的问题:能用空指针调用类的成员函数(gcc,vs2013下都可以). 例子: class animal { public: void sleep(){ ...

  8. boost::function 通过boost::bind调用类成员函数

    1. 首先引用boost::function和boost::bind的头文件和库: #include "boost/bind.hpp" #include "boost/f ...

  9. C++类的成员函数(在类外定义成员函数、inline成员函数)

    类的成员函数(简称类函数)是函数的一种,它的用法和作用和前面介绍过的函数基本上是一样的,它也有返回值和函数类型,它与一般函数的区别只是:它是属于一个类的成员,出现在类体中.它可以被指定为private ...

随机推荐

  1. shell小技巧(4)AIX和Linux计算天前日期

    Linux计算天前日期: date -d "- day" +%Y%m%d AIX计算5天前日期: perl -e "use POSIX qw(strftime); pri ...

  2. 一句Delete..In.. 删除语句的优化

    实验环境: # 类别 版本 1 操作系统 Win10 2 数据库 Oracle Database 11g Enterprise Edition Release 11.2.0.1.0 - 64bit P ...

  3. 20190923-04Linux用户管理命令 000 012

     useradd 添加新用户 1.基本语法 useradd 用户名 (功能描述:添加新用户) useradd -g 组名 用户名 (功能描述:添加新用户到某个组) 2.案例实操 (1)添加一个用户 [ ...

  4. python应用 曲线拟合 01

    双指数函数 待拟合曲线为 y(x) = bepx + ceqx import matplotlib.pyplot as plt x = ([0.05, 0.1, 0.15, 0.2, 0.25, 0. ...

  5. SpringMVC-08-SpringMVC层编写

    SpringMVC层编写 web.xml DispatcherServlet <!--DispatcherServlet--> <servlet> <servlet-na ...

  6. Python反转链表

    # -*- coding:utf-8 -*- # class ListNode: # def __init__(self, x): # self.val = x # self.next = None ...

  7. Linux常用命令详解(2)

    aliasunaliasunamesuhostnamehistorywhichwcwwhowhoamipingkillseqdudffreedate 命令详解 1. alias 设置.’查看别名 实例 ...

  8. python 中简单的输出语句

    1 python 中简单的输出语句 #coding:utf-8#输出的是整数,得到的也是整数,用raw_inputusername=raw_input('请输入用户名:')#输出的是整数或者字符串,得 ...

  9. uniapp vue v-html,显示富文本,内容img图片超出解决办法

    uniapp h5中,v-html,img图片中style=width:auto;会显示图片原来的尺寸,会超出屏幕,替换成width:100%,这样就不会超出屏幕 重要的地方,例如<img sr ...

  10. Redis常见的八道面试题

      一.memcached与redis的区别? 1.存储方式不同.memcached把数据全部存在内存之中,断电之后会挂掉,而redis虽然也用到了内存,但是会有部分数据存在硬盘中,保证数据持久性. ...