免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
1234567
最近访问板块 发新帖
楼主: cascle
打印 上一主题 下一主题

怎么样才能传多个参数给signal函数的回调函数? [复制链接]

论坛徽章:
0
61 [报告]
发表于 2010-05-11 11:42 |只看该作者
弱弱的说一句

传指针也可以吧,指针也是一个整形的,

在回调函数中根据整形数据取得指针指向的地址应该没问题吧

论坛徽章:
11
未羊
日期:2013-12-16 12:45:4615-16赛季CBA联赛之青岛
日期:2016-04-11 19:17:4715-16赛季CBA联赛之广夏
日期:2016-04-06 16:34:012015亚冠之卡尔希纳萨夫
日期:2015-11-10 10:04:522015亚冠之大阪钢巴
日期:2015-07-30 18:29:402015亚冠之城南
日期:2015-06-15 17:56:392015亚冠之卡尔希纳萨夫
日期:2015-05-15 15:19:272015亚冠之山东鲁能
日期:2015-05-14 12:38:13金牛座
日期:2014-12-04 15:34:06子鼠
日期:2014-10-16 13:40:4715-16赛季CBA联赛之八一
日期:2016-07-22 09:41:40
62 [报告]
发表于 2010-05-11 12:49 |只看该作者
如果LZ的程序是单线程,那么我认为没必要搞那么复杂,直接调用就行了。
如果LZ的程序是多线程,希望用信号 ...
w_anthony 发表于 2010-05-11 10:42


你说的这些都是业务逻辑了, 这里到没必要考虑这些。
全局实际上确实不是很好看, 不过相对汇编或者机器码来说, 浅显的多, 自然解决的问题范围也狭小的多, 仅限于此而已。
就这个case, 现在横看竖看, 还是 sigqueue 好

论坛徽章:
2
程序设计版块每日发帖之星
日期:2015-06-17 22:20:00每日论坛发贴之星
日期:2015-06-17 22:20:00
63 [报告]
发表于 2010-05-11 15:10 |只看该作者
提示: 作者被禁止或删除 内容自动屏蔽

论坛徽章:
0
64 [报告]
发表于 2010-05-11 15:44 |只看该作者
我觉得还是用sigaction这个函数比较好~!signal是不可靠信号

论坛徽章:
2
青铜圣斗士
日期:2015-11-26 06:15:59数据库技术版块每日发帖之星
日期:2016-07-24 06:20:00
65 [报告]
发表于 2010-05-12 14:21 |只看该作者
回复 59# w_anthony

问题是没有。
0xC7、0x04、0x24 加上后面4个字节的指令(后面4个字节由第1个指令填入) 刚好把返回地址填了, 把栈也给平了。

真正用的时候当然是不可能用栈上的, 这只是一个演示……

你要我怎么写呢? 用malloc 肯定会被人说DEP。
VirtualAlloc或mmap都是大粒度分配, 肯定又会被说浪费内存了: 为了这么小一个功能, 去分配一页, 甚至一个区域。

而这些都不是技术难点, 内存池只是一种常规技术, 真要使用VirtualAlloc, mmap去分配的话肯定是要搭配一个的。

论坛徽章:
0
66 [报告]
发表于 2010-05-12 15:21 |只看该作者
回复 1# cascle


    一般回调的时候都是传递结构体地址的,
将你要返回的参数定义在结构体中,
这样就可以达到返回多个值的效果了

论坛徽章:
9
摩羯座
日期:2013-08-15 15:18:48狮子座
日期:2013-09-12 18:07:47金牛座
日期:2013-09-16 13:23:09辰龙
日期:2013-10-09 09:03:27白羊座
日期:2013-10-17 13:32:44子鼠
日期:2014-04-23 15:09:38戌狗
日期:2014-09-17 11:37:542015年亚洲杯之韩国
日期:2015-03-26 10:16:442015亚冠之武里南联
日期:2015-08-18 14:55:52
67 [报告]
发表于 2010-05-12 16:33 |只看该作者
回复 65# OwnWaterloo


    你是对的,我想错了。。。
这种方法我觉得在stdcall上面插参数太好用了,cdecl不太好用,如果是只钩一次的用法的话,不能递归,也不能重入。

论坛徽章:
2
青铜圣斗士
日期:2015-11-26 06:15:59数据库技术版块每日发帖之星
日期:2016-07-24 06:20:00
68 [报告]
发表于 2010-05-12 16:46 |只看该作者
回复 67# w_anthony

嗯, stdcall可以很简单的做成stateless的……  就随便怎么弄了。
cdecl。。。 要调整栈, 很麻烦……
如果是为每种签名设计一种layout, 也是可以做成stateless, 但是要写好多代码啊……
写代码问题都不大, 可以自动生成。  关键是使用……

R (*f1)(void*, int) -> R (*f1)(void* )  需要使用layout1。
R (*f2)(void*, int, int) -> R (*f1)(void* ,int )  需要使用layout2。
如是等等……

如果可以用C++, 都还好, layout类型可以根据参数来推导。
C就没什么好办法了……


有没有更优化的方法?


btw: 其实在i386下可以对几乎所有签名使用相同的layout是一种特例……
因为stdcall, cdecl都是用栈传递参数。
无须知道究竟有多少, 只需要将那个ctx插入进去就可以了。

在其他机器上, 如果默认优先使用寄存器, 那可能就不得不为每种签名设计相应的layout。。。
(即使是在i386下, 如果用fastcall, 也会出现这种情况……)

论坛徽章:
2
青铜圣斗士
日期:2015-11-26 06:15:59数据库技术版块每日发帖之星
日期:2016-07-24 06:20:00
69 [报告]
发表于 2010-05-12 17:15 |只看该作者
写得比较乱……   我整理一下……

函数签名与layout的关系, 可以是多对多的, 也可以是多对一的。

就举2种签名吧:

  1. void (*legacy1)(void);
  2. int  (*legacy2)(void const*, void const*);
复制代码
两种在C/C++标准库中都存在。atexit, set_newhandler, qsort, bsearch。

但希望它们的签名是这样:

  1. void (*expect1)(void* ctx);
  2. int  (*expect2)(void* ctx, void const*, void const*);
复制代码
一种方式是每种签名对应一种layout。
一种方式是尽可能让多种签名共用一种layout。

一对一的优势是可以给实现方面提供更多的信息。
这不单关系到实现的质量(比如上面说的, 是否是stateless),
甚至关系到是否能够实现(比如上面说的, fastcall)。

而多对一的方式, 主要是方便记忆……
不需要记住到底应该用哪一个……
因为这个是没有类型检查的, 只能靠文档来描述。
如果记错, 肯定是要跑飞的。

当然, 如果client可以使用C++, 而且不是VC6, 就可以用函数的签名去推导正确的layout。
所以多对一的这个优势是对C而言的。


因为这个东西……  不是凭空就想去这么做…… 我是被逼无奈啊……
以前我都用各种方法绕过去了(因为很多这种烂回调都是stdcall的)
但遇见OpenCV后我败了……

  1. typedef void (*CvTrackbarCallback)(int pos);
复制代码
cdecl的。  它通知“某个” trackbar被修改到pos的位置, 但就是不告诉你是哪个trackbar被修改……

要么:

  1. container all_trackbar;
  2. void notify_all(int )
  3. {
  4.       所有trackbar注意啊,
  5.       你们当中某个被修改了,
  6.       自己检查, 然后更新
  7. }
复制代码
要么:

  1. trackbar1;
  2. void update1(int pos) { trackbar1.update(pos); }

  3. trackbar2;
  4. void update2(int pos) { trackbar2.update(pos); }

  5. trackbar3;
  6. void update3(int pos) { trackbar3.update(pos); }

  7. ...
复制代码
无论那种, 我都觉得太难看……


为了应付实际的问题, 所以就弄出了这样一种layout。
而且, 它恰好是多对一的。但不是stateless的(虽然暂时够用)。



如果要将这种方案继续范化, 如果考虑到移植性, 我觉得一对一才是王道……

界面需要给实现留有余地, 否则实现要么完成得很差, 要么根本无法完成功能。
这些legacy代码已经犯过这样的错误(这种烂回调, 还有strtok, 还有fd)。
为了修正它们的错误已经要花费不少功夫, 不能让解决问题的方案自身留下问题然后再用方案去弥补……
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP