一个函数指针的理解:
有一段程序存储在起始地址为 0的一段内存上,如果我们想要调用这段程序,请问该如何去做?
答案是 (*(void (*)( ) )0)( )。
首先,最基本的函数声明: void function (paramList);
最基本的函数调用: function(paramList);
鉴于问题中的函数没有参数,函数调用可简化为 function();
根据问题描述,可以知道 0是这个函数的入口地址,也就是说,0是一个函数的指针。
使用函数指针的函数声明形式是:void (*pFunction)(),相应的调用形式是: (*pFunction)(),
则问题中的函数调用可以写作:(*0)( )。
大家知道,函数指针变量不能是一个常数,因此上式中的 0必须要被转化为函数指针。
我们先来研究一下,对于使用函数指针的函数:
比如 void (*pFunction)( ),函数指针变量的原型是什么?
这个问题很简单,pFunction函数指针原型是( void (*)( ) ),即去掉变量名,
清晰起见,整个加上()号。
所以将 0强制转换为一个返回值为void,参数为空的函数指针如下:( void (*)( ) )。
OK,结合2)和3)的分析,结果出来了,那就是:(*(void (*)( ) )0)( ) 。
答案分析:从头到尾理解答案
(void (*)( )) ,是一个返回值为void,参数为空的函数指针原型。
(void (*)( ))0,把0转变成一个返回值为void,参数为空的函数指针,指针指向的地址为0.
*(void (*)( ))0,前面加上*表示整个是一个返回值为void的函数的名字
(*(void (*)( ))0)( ),这当然就是一个函数了。
我们可以使用 typedef清晰声明如下:
typedef void (*pFun)();
这样定义之后,pFun就是一个返回类型为void无参数的函数指针变量了。
这样函数变为 (*(pFun)0)();
----
在调用动态库时,习惯用typedef重新定义动态库函数中的函数地址(函数指针),
如在动态库(test.dll)中有如下函数:
int DoCase(int, long);
则,在调用动态库是有两种方法:
1. 先声明一个与动态库中类型一致的指针函数变量:
int (*DOCASE)(int ,long); //用于指向动态库中的DoCase函数地址
HINSTANCE gLibMyDLL = NULL;
gLibMyDLL = LoadLibrary("test.dll");
if(gLibMyDLL != NULL)
{
DOCASE = (int(*)(int,long))GetProcAddress(gLibMyDLL, "DoCase");
}
int s = DOCASE(1,1000);
2.用typedef定义一个指针函数:
typedef (*DOCASE)(int ,long);
HINSTANCE gLibMyDLL = NULL;
DOCASE _docase;
gLibMyDLL = LoadLibrary("test.dll");
if(gLibMyDLL != NULL)
{
_docase = (DOCASE)GetProcAddress(gLibMyDll, "DoCase");
}
int s=_docase(1,1000);
----------------
在C++类中使用函数指针。
//typedef 返回类型(类名::*新类型)(参数表)
class CA
{
public:
char lcFun(int a){ return; }
};
CA ca;
typedef char (CA::*PTRFUN)(int);
PTRFUN pFun;
void main()
{
pFun = CA::lcFun;
ca.(*pFun)(2);
}
指针的定义与使用都加上了“类限制”或“对象”,用来指明指针指向的函数是哪个类的,
这里的类对象也可以是使用new得到的。
如:
CA *pca = new CA;
pca->(*pFun)(2);
delete pca;
而且这个类对象指针可以是类内部成员变量,你甚至可以使用this指针。
如:类CA有成员变量PTRFUN m_pfun;
void CA::lcFun2()
{
(this->*m_pFun)(2);
}
一句话,使用类成员函数指针必须有“->*”或“.*”的调用。
--------------------
void test(void* );
void tt()
{
printf("kao,没玩过这种\n");
}
int main(int argc, char* argv[])
{
typedef void(*Fun)();
Fun mytest;
mytest = tt;
test((void*)mytest);
return 0;
}
void test(void * p)
{
(*(void(*)())p)();
}