首页
社区
课程
招聘
[求助]指针数组的元素是函数地址,急求解!!
发表于: 2013-2-3 18:15 4869

[求助]指针数组的元素是函数地址,急求解!!

2013-2-3 18:15
4869
static NTSTATUS (*fcntab[])(PDEVICE_EXTENSION pdx, PIRP Irp) =
       {
        DefaultPnpHandler,
        DefaultPnpHandler,
        HandleRemoveDevice,       
        DefaultPnpHandler,
        DefaultPnpHandler,
        ...
        DefaultPnpHandler,
        }
   
NTSTATUS DefaultPnpHandler(PDEVICE_EXTENSION pdx, PIRP Irp)
{...}

NTSTATUS HandleRemoveDevice(PDEVICE_EXTENSION pdx, PIRP Irp)
{...}

fcn = stack->MinorFunction;  ...
这是驱动开发详解的WDM驱动处理IRP_MJ_PNP的例子的一部分,书中是这样调用的函数:
(*fcntab[fcn])(pdx, Irp);

不太理解,我认为应该是(fcntab[fcn])(pdx, Irp),fcntab[fcn]前面不加*,
NTSTATUS (*fcntab[]) 这是一个指针数组,函数名DefaultPnpHandler和HandleRemoveDevice可以理解为指针,
fcntab[0]就是指针数组的第一个元素DefaultPnpHandler,
fcntab[2]是HandleRemoveDevice,
那为什么调用函数是(*fcntab[fcn])(pdx, Irp);
//这不就翻译成*DefaultPnpHandler(pdx, Irp)或*HandleRemoveDevice(pdx, Irp)
而不是(fcntab[fcn])(pdx, Irp)
       //这样才是DefaultPnpHandler(pdx, Irp)或HandleRemoveDevice(pdx, Irp)

我哪理解有问题,求解释解释,谢谢

[培训]内核驱动高级班,冲击BAT一流互联网大厂工作,每周日13:00-18:00直播授课

收藏
免费 0
支持
分享
最新回复 (6)
雪    币: 228
活跃值: (115)
能力值: ( LV5,RANK:70 )
在线值:
发帖
回帖
粉丝
2
指针数组傻傻分不清楚!
2013-2-3 20:18
0
雪    币: 3366
活跃值: (1333)
能力值: ( LV4,RANK:40 )
在线值:
发帖
回帖
粉丝
3
话说 你都把我给绕晕了 回去翻下C\C++的书 看看指针、数组这一块吧 你没理解透
2013-2-3 22:13
0
雪    币: 264
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
4
这个东西,下个断点看一下值,跟一下就出来了,没必要太纠结,假设,F[0]是指针数组变量, F[0]的值是指向函数的变量,该变量的值就是函数地址,即*F[0]等价于取函数地址值,后面括号是调用了
2013-2-3 23:49
0
雪    币: 32
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
5
ms两种写法都行的。。。。。。
2013-2-4 01:57
0
雪    币: 4817
活跃值: (23)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
6
[QUOTE=chenjimind;1140570]static NTSTATUS (*fcntab[])(PDEVICE_EXTENSION pdx, PIRP Irp) =
       {
        DefaultPnpHandler,
        DefaultPnpHandler,
        HandleRemov...[/QUOTE]

假设不加*,那就是static NTSTATUS (fcntab[])(PDEVICE_EXTENSION pdx, PIRP Irp);

再假设不用数组,或者数组个数是1,反正就只是存一个函数,那还可以这样定义:
static NTSTATUS (fcntab)(PDEVICE_EXTENSION pdx, PIRP Irp);

那我就要问你了,你定义的是函数指针,还是函数呢?
更关键是,这都成声明了,而不是定义。(声明和定义的区别就不用我说了吧)

本意是我们要找块空间,存放函数的地址,这块空间大小sizeof(DWORD_PTR),其实你定义个DWORD_PTR *Fun是可以的,上面的定义只不过是除了分配空间外同时定义了函数类型而已。

说说两种定义的不同,char Var[], char *PtrVar[],区别在哪儿?Var[0]只有一个字节,而PtrVar[0]却占用4个字节。前面是定义了char类型变量,后面是定义了指向char类型的指针变量,说白了,Var[0]实现了这个变量,而PtrVar[0]却要指向Var[0]才有效(PtrVar[0]=&Var[0])。

你的问题也如此,如果你定义(假设可以定义,呵呵,实际上不能这么写)了
static NTSTATUS (fcntab[])(PDEVICE_EXTENSION pdx, PIRP Irp);
那你是定义了N个函数,而不是N个函数指针啊。

至于调用,(*fcntab[fcn])(pdx, Irp)和(fcntab[fcn])(pdx, Irp)在微软编译器中,是一样的,你想想,如果fcntab[fcn]是一个DWORD指针,那么*fcntab[fcn]就是个DWORD值,但如果fcntab[fcn]是一个函数指针,那*fcntab[fcn]有何意义,能取出整个函数?微软编译器中,这两个同等对待。

(*fcntab[fcn])(pdx, Irp);
(fcntab[fcn])(pdx, Irp);
是一样的。
2013-2-4 10:44
0
雪    币: 113
活跃值: (100)
能力值: ( LV4,RANK:50 )
在线值:
发帖
回帖
粉丝
7
楼上解释的很清楚。
2013-2-5 12:09
0
游客
登录 | 注册 方可回帖
返回
//