我试着用下面这个union结构把类成员函数转为线程回调函数 union {
unsigned int (__stdcall *threadfunc)(void *);
unsigned int (__stdcall A::*memberfunc)(void *);
}btex_proc;但是在线程函数使用_beginthreadex中传入的类对象地址,
((A*)param)->printb(); 这个调用会失败为什么?另外还想问下,这种方法有什么缺陷吗?我的测试代码#include <stdio.h>
#include <windows.h>
#include <process.h>typedef unsigned int * PBEGINTHREADEX_ID;class A
{
public:
int class_id_;
A(int class_id):class_id_(class_id){}
void printb()
{
printf("%d\n", class_id_);
}
unsigned int WINAPI beginthreadex_func(LPVOID param)
{
// 强转后,param并不指向a, 所以class_id_是一个未知的数,printf 打印class_id_失败
//((A*)param)->printb();
// 但可以直接调用成员函数
printb();
return 0;
}
};
int main()
{
A a(1);
HANDLE thread_id;
union {
unsigned int (__stdcall *threadfunc)(void *);
unsigned int (__stdcall A::*memberfunc)(void *);
}btex_proc; btex_proc.memberfunc = &A::beginthreadex_func; _beginthreadex(NULL, 0, btex_proc.threadfunc, (LPVOID)&a, 0, (PBEGINTHREADEX_ID)&thread_id); Sleep(10000);
return 0;
}
unsigned int (__stdcall *threadfunc)(void *);
unsigned int (__stdcall A::*memberfunc)(void *);
}btex_proc;但是在线程函数使用_beginthreadex中传入的类对象地址,
((A*)param)->printb(); 这个调用会失败为什么?另外还想问下,这种方法有什么缺陷吗?我的测试代码#include <stdio.h>
#include <windows.h>
#include <process.h>typedef unsigned int * PBEGINTHREADEX_ID;class A
{
public:
int class_id_;
A(int class_id):class_id_(class_id){}
void printb()
{
printf("%d\n", class_id_);
}
unsigned int WINAPI beginthreadex_func(LPVOID param)
{
// 强转后,param并不指向a, 所以class_id_是一个未知的数,printf 打印class_id_失败
//((A*)param)->printb();
// 但可以直接调用成员函数
printb();
return 0;
}
};
int main()
{
A a(1);
HANDLE thread_id;
union {
unsigned int (__stdcall *threadfunc)(void *);
unsigned int (__stdcall A::*memberfunc)(void *);
}btex_proc; btex_proc.memberfunc = &A::beginthreadex_func; _beginthreadex(NULL, 0, btex_proc.threadfunc, (LPVOID)&a, 0, (PBEGINTHREADEX_ID)&thread_id); Sleep(10000);
return 0;
}
static方法我知道,不过我是在试其他方法
ps : 这个程序是可以运行的没用的
unsigned int (__stdcall *threadfunc)(void *);
unsigned int (__stdcall A::*memberfunc)(void *);
}btex_proc;
换成
union {
unsigned int (__stdcall *threadfunc)(void *);
unsigned int (__stdcall A::*memberfunc)(void);
}btex_proc; unsigned int WINAPI beginthreadex_func(LPVOID param)
换成
unsigned int __stdcall beginthreadex_func(void)
{
printf("%p",this);
这里this就是传进来的&a
}你这样做是假定了类成员函数指针的开头放的是成员函数的地址
btex_proc.threadfunc与&a是如何关联起来的->假定了类成员函数指针的开头放的是成员函数的地址
指针的长度都为4,“类成员函数指针的开头”是什么意思,不明白
union {
unsigned int (__stdcall *threadfunc)(void *);
unsigned int (__stdcall A::*memberfunc)(void);
}btex_proc;
为什么可以这样转换,网上的资料只是说,指针的长度一样,没有具体深入的分析
所以我不是很清楚为什么可以转换
所以不能确定这个转换有什么风险
btex_proc.memberfunc = &A::beginthreadex_func;
并不是假定,是由这句来指定