找回密码
 注册
搜索
查看: 1226|回复: 18

[讨论] 关于函数指针的疑问,

[复制链接]
发表于 2007-1-22 10:24:22 | 显示全部楼层 |阅读模式
关于函数指针的疑问
在消息传递的过程中,经常遇到call back 函数,使用函数指针来调用.
现在的问题时,我发现函数指针在传递的时候没有按照传值的规定.是把调用函数的备份传入了吗?请看下面的例子.
typedef int (*PF)();
PF regirster(PF pf);
PF regirster(PF pf)
{
return pf;
}
....
int funcA()
{
...
}
PF pfunc;
pfunc = regirster(funcA);

//这里出现的问题是:
funcA的地址是: 0x00401150
而 pf的值是 : 0x00401014
从而: pfunc的值是: 0x00401014

调用正确, 问题是:PF regirster(PF pf) 为什么传的值为什么不是funcA的地址??
谢谢,
 楼主| 发表于 2007-1-22 10:24:22 | 显示全部楼层 |阅读模式
关于函数指针的疑问
在消息传递的过程中,经常遇到call back 函数,使用函数指针来调用.
现在的问题时,我发现函数指针在传递的时候没有按照传值的规定.是把调用函数的备份传入了吗?请看下面的例子.
typedef int (*PF)();
PF regirster(PF pf);
PF regirster(PF pf)
{
return pf;
}
....
int funcA()
{
...
}
PF pfunc;
pfunc = regirster(funcA);

//这里出现的问题是:
funcA的地址是: 0x00401150
而 pf的值是 : 0x00401014
从而: pfunc的值是: 0x00401014

调用正确, 问题是:PF regirster(PF pf) 为什么传的值为什么不是funcA的地址??
谢谢,
发表于 2007-1-23 08:51:31 | 显示全部楼层
传指针的指针试试吧
点评回复

使用道具 举报

发表于 2007-1-27 14:55:54 | 显示全部楼层
你怎么知道“funcA的地址是: 0x00401150”?
如果是基于ARM的平台,也许会涉及到THUMB指令集和ARM指令集的问题,
也就是说,对同一个函数,既有THUMB指令入口又有ARM指令入口。
另外,你的regirster函数只有这点内容?
能否描述得更详细些?我猜你肯定是漏掉了某些细节。
点评回复

使用道具 举报

发表于 2007-1-30 16:52:00 | 显示全部楼层
这个问题其实还是不难 (*pfunc)等于 0x00401150 就是了  呵呵 。。。
点评回复

使用道具 举报

发表于 2007-1-30 16:53:17 | 显示全部楼层
因为你调用的时候会是这样 (*pfunc)();     ^_^
点评回复

使用道具 举报

发表于 2007-1-31 20:44:48 | 显示全部楼层
to JamesCarter,你的理解不确切。

to testcommand,
某些平台某些编译器在某些情况下会产生函数跳转表,我猜你这里就是这种情况。
你看看0x00401014地址处是什么指令,也许就是一条JUMP指令,
直接或者间接跳转到0x00401150处(也就是funcA的实际入口)。
点评回复

使用道具 举报

发表于 2007-2-1 09:42:05 | 显示全部楼层
to  erichain:  我是这样理解的,pfunc是一个指针,这个指针里面存放的值就是函数funcA的值,所以(*pfunc)的值就是等于 0x00401150。   0x00401014是pfunc指针变量本身的地址值。
点评回复

使用道具 举报

发表于 2007-2-1 18:54:45 | 显示全部楼层
to JamesCarter,
函数指针和普通指针是不同的,
普通指针指向一个object,
如果是非复合类型(比如不是结构体类型),可以dereference说(*p)的值是多少,
而指针的具体类型主要用来说明object的结构;
函数指针指向一个function,更明确地讲,
pfunc里保存的是一条指令的地址(也有可能是地址偏移量,平台不同实现方式也不尽相同),
所以也就不能说(*pfunc)的值是多少了,
而指针的具体类型主要用来说明函数调用规则。
楼主这里的实际情况很可能是,
pfunc里保存的是一条JUMP指令的地址
(也就是0x00401014,注意这个不是pfunc指针变量本身的地址值,
而是pfunc指针变量的值。pfunc指针变量本身的地址值用&pfunc表示。),
这条JUMP指令会跳转到另外一个地址,也许那个地址处又是一条跳转指令,
或者也许就是funcA的入口地址(0x00401150),开始执行funcA的真正指令。
点评回复

使用道具 举报

发表于 2007-1-23 08:51:31 | 显示全部楼层
传指针的指针试试吧
点评回复

使用道具 举报

发表于 2007-1-27 14:55:54 | 显示全部楼层
你怎么知道“funcA的地址是: 0x00401150”?
如果是基于ARM的平台,也许会涉及到THUMB指令集和ARM指令集的问题,
也就是说,对同一个函数,既有THUMB指令入口又有ARM指令入口。
另外,你的regirster函数只有这点内容?
能否描述得更详细些?我猜你肯定是漏掉了某些细节。
点评回复

使用道具 举报

发表于 2007-1-30 16:52:00 | 显示全部楼层
这个问题其实还是不难 (*pfunc)等于 0x00401150 就是了  呵呵 。。。
点评回复

使用道具 举报

发表于 2007-1-30 16:53:17 | 显示全部楼层
因为你调用的时候会是这样 (*pfunc)();     ^_^
点评回复

使用道具 举报

发表于 2007-1-31 20:44:48 | 显示全部楼层
to JamesCarter,你的理解不确切。

to testcommand,
某些平台某些编译器在某些情况下会产生函数跳转表,我猜你这里就是这种情况。
你看看0x00401014地址处是什么指令,也许就是一条JUMP指令,
直接或者间接跳转到0x00401150处(也就是funcA的实际入口)。
点评回复

使用道具 举报

发表于 2007-2-1 09:42:05 | 显示全部楼层
to  erichain:  我是这样理解的,pfunc是一个指针,这个指针里面存放的值就是函数funcA的值,所以(*pfunc)的值就是等于 0x00401150。   0x00401014是pfunc指针变量本身的地址值。
点评回复

使用道具 举报

发表于 2007-2-1 18:54:45 | 显示全部楼层
to JamesCarter,
函数指针和普通指针是不同的,
普通指针指向一个object,
如果是非复合类型(比如不是结构体类型),可以dereference说(*p)的值是多少,
而指针的具体类型主要用来说明object的结构;
函数指针指向一个function,更明确地讲,
pfunc里保存的是一条指令的地址(也有可能是地址偏移量,平台不同实现方式也不尽相同),
所以也就不能说(*pfunc)的值是多少了,
而指针的具体类型主要用来说明函数调用规则。
楼主这里的实际情况很可能是,
pfunc里保存的是一条JUMP指令的地址
(也就是0x00401014,注意这个不是pfunc指针变量本身的地址值,
而是pfunc指针变量的值。pfunc指针变量本身的地址值用&pfunc表示。),
这条JUMP指令会跳转到另外一个地址,也许那个地址处又是一条跳转指令,
或者也许就是funcA的入口地址(0x00401150),开始执行funcA的真正指令。
点评回复

使用道具 举报

发表于 2007-2-28 16:32:58 | 显示全部楼层
to  erichain:  你好,我的邮箱是jack47040111@163.com, 可否发邮件给你的联系,希望后面遇到问题可以互相帮助,以及资源共享。
点评回复

使用道具 举报

发表于 2007-3-1 15:24:17 | 显示全部楼层
to  erichain:
我是这样理解的,函数指针其实就是指向指针的指针。

PF regirster(PF pf);这个函数本身是传值,并不是传址的。返回时其实系统内部声明了一个指针指向pf地址,但是返回的是这个指针的地址,也就是0x00401014。但是这个地址对应得值是0x00401150,
所以最后还是会执行funcA的真正指令。
点评回复

使用道具 举报

发表于 2007-3-1 15:29:42 | 显示全部楼层
一般函数fun(void *p);
本身在执行的时候,内部会存在一份拷贝指针,所以并不会把p的地址传进去,而是那份拷贝指针的地址。
点评回复

使用道具 举报

高级模式
B Color Image Link Quote Code Smilies

本版积分规则

Archiver|手机版|小黑屋|52RD我爱研发网 ( 沪ICP备2022007804号-2 )

GMT+8, 2024-12-24 03:30 , Processed in 0.062451 second(s), 16 queries , Gzip On.

Powered by Discuz! X3.5

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表