先介绍两个概念:
__cdecl
__cdecl 是 C Declaration 的缩写,表示 C语言默认的函数调用方法:
所有参数从右到左依次入栈,这些参数由调用者清除,称为手动清栈。
被调用函数不会要求调用者传递多少参数,调用者传递过多或者过少的参数,甚至完全不同的参数都不会产生编译阶段的错误。
__stdcall
__stdcall 是 Standard Call 的缩写,是 C++ 的标准调用方式:
所有参数从右到左依次入栈,如果是调用类成员的话,最后一个入栈的是 this指针。这些堆栈中的参数由被调用的函数在返回后清除,
使用的指令是 retnX,X 表示参数占用的字节数,CPU 在 ret 之后自动弹出 X 个字节的堆栈空间,称为自动清栈。
函数在编译的时候就必须确定参数个数,并且调用者必须严格的控制参数的生成,不能多,不能少,否则返回后会出错。
__thiscall
__thiscall 是为了解决类成员调用中 this 指针传递而规定的。
__thiscall 要求把 this 指针放在特定寄存器中,该寄存器由编译器决定。VC 使用 ecx,Borland 的 C++ 编译器使用 eax。返回方式和 __stdcall 相当。
C 语言中不加说明默认函数为 __cdecl 方式(C中也只能用这种方式),C++ 也一样,但是默认的调用方式可以在 IDE 环境中设置。
注意:
pthread_create()函数的线程函数必须是静态的函数,以标准的__cdecl的方式调用的,而C++的成员函数是以__thiscall的方式调用的,相当于一个普通函数有一个默认的const ClassType* this参数。
C语言程序可以看成由一系列外部对象构成,这些外部对象可能是变量或函数。而内部变量是指定义在函数内部的函数参数及变量。外部变量定义在函数之外,因此可以在许多函数中使用。由于C语言不允许在一个函数中定义其它函数,因此函数本身只能是“外部的”。因此C语言的函数都是可以作为线程入口函数的。但是对于C++而言,如果要做为线程入口函数,必须是static函数,即:在C++的类中,普通成员函数不能作为pthread_create的线程函数,如果要作为pthread_create中的线程函数,必须是static !因为:
回调函数是基于C编程的Windows SDK的技术,不是针对C++的,程序员可以将一个C函数直接作为回调函数,
但是如果试图直接使用C++的非static成员函数作为回调函数将发生错误,甚至编译就不能通过。
普通的C++成员函数都隐含了一个传递函数作为参数,亦即“this”指针,C++通过传递一个指向自身的指针给其成员函数从而实现程序函数可以访问C++的数据成员。这也可以理解为什么C++类的多个实例可以共享成员函数但是确有不同的数据成员。由于this指针的作用,使得将一个CALLBACK型的成员函数作为回调函数安装时就会因为隐含的this指针使得函数参数个数不匹配,从而导致回调函数安装失败(这就是__cdecl的原因,参见上面__cdecl的解释),而static则因为没有该this指针参数,因此不受影响。
其他的方法,参考:blog.csdn.net/this_capslo…