我试着用下面这个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;
}

解决方案 »

  1.   


    static方法我知道,不过我是在试其他方法
    ps : 这个程序是可以运行的没用的
      

  2.   

    union   { 
    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
    }你这样做是假定了类成员函数指针的开头放的是成员函数的地址
      

  3.   

    我不明白,为什么printf("%p",this);这里的this就是&a呢。
    btex_proc.threadfunc与&a是如何关联起来的->假定了类成员函数指针的开头放的是成员函数的地址
    指针的长度都为4,“类成员函数指针的开头”是什么意思,不明白
    union {  
    unsigned int (__stdcall *threadfunc)(void *);  
    unsigned int (__stdcall A::*memberfunc)(void);  
    }btex_proc;
    为什么可以这样转换,网上的资料只是说,指针的长度一样,没有具体深入的分析
    所以我不是很清楚为什么可以转换
    所以不能确定这个转换有什么风险
      

  4.   

    “假定了类成员函数指针的开头放的是成员函数的地址”
    btex_proc.memberfunc   =   &A::beginthreadex_func; 
    并不是假定,是由这句来指定
      

  5.   

    那你怎么知道threadfunc成员就是其地址