偷懒是人类进步的阶梯,请问大佬们 C 如何运行时生成函数指针

2020-11-23 20:51:03 +08:00
 HHPLow

有两个函数的参数 A,B 我想在调用 func(A, B)时候, 自动调用到 func_a1_b2(); 或者 func_a2_b2();

之前拿 switch case 做,写了半天发现太蠢了... 求大佬们指教。

3376 次点击
所在节点    C
19 条回复
lcdtyph
2020-11-23 20:54:40 +08:00
我觉得你连需求都没描述清楚……

盲建议个跳转表吧
Ediacaran
2020-11-23 21:01:24 +08:00
想要柯里化还是闭包?

C 里面都没有常规能实现的方法
ETiV
2020-11-23 21:34:27 +08:00
Tony042
2020-11-23 21:36:06 +08:00
函数重载?
HHPLow
2020-11-23 21:55:37 +08:00
@ETiV 多谢!之前不明白反射是个啥现在知道了😂

的确就是想按照名称反射一个函数出来,我朝着这个方向找找。

@lcdtyph 多谢! 也是能实现的,但是好像还要维护一个表,有点麻烦
irytu
2020-11-23 22:01:40 +08:00
不太明白你的描述 不过运行时打桩了解一下 查一下 LD_PRELOAD 这个环境变量 封装一下你真正关心的函数

不确定是不是你需要的这种

```
func(A, B)
{
func_a1_b2();
}
```
elfive
2020-11-23 22:17:42 +08:00
@ETiV #3 这是 SMC ( self-modifying code )吧
ysc3839
2020-11-23 22:22:09 +08:00
意思是通过函数名称的字符串,调用对应函数?这个必须建个表才能实现。
heqing
2020-11-23 22:30:27 +08:00
可以参考一下 Windows 平台下 MFC 消息映射的实现方式, 通过宏定义将常量映射到函数调用.
DoctorCat
2020-11-23 23:16:57 +08:00
支持 @heqing 的建议。通过宏定义是最简单的方式了,不过不适用于 runtime 阶段。
oahebky
2020-11-23 23:27:14 +08:00
《 head first C 》「函数指针」一节可以看一下。

通过数组和函数指针的映射“初始化”好了之后可以一行代码调用不同函数;不用写一堆判断。

或许是你想实现的。
no1xsyzy
2020-11-24 01:31:43 +08:00
根据参数修改实际调用函数?
这个 SICP 第一章两段代码实现了一个非常基础的跳转表,然后两笔带过了,然而就是这两段代码,稍微再扩充一倍代码量就是一个 multi-dispatcher……

不过,简单的话,如果你的伪代码是这样的:
func(A,B)(C) =>
if A==1 and B==1 then
func_a1_b1(C)
else if A==2 and B==2 then
func_a2_b2(C)
end

那可以用 hashmap 来实现
函数指针不需要运行时生成,静态生成,运行时保存进 hashmap 就行
GeruzoniAnsasu
2020-11-24 01:40:22 +08:00
dlopen dlsym
loadlibrary getprocessaddress


“运行时获得函数地址” 只有这种办法
其它的都只是编译期把地址存到固定地方而已
felixin
2020-11-24 01:40:25 +08:00
这就是多态,触摸到软件工程的边了
GeruzoniAnsasu
2020-11-24 01:42:50 +08:00
*getprocaddress

或者可以用宏来自动给新加的函数增加额外注册逻辑
Maboroshii
2020-11-24 02:06:25 +08:00
写一个脚本来生成初始化的部分就省事了吧。

http 服务的路由也是这个啊,识别 uri,然后调用对应的方法去处理请求。 方向都差不多,只是实现细节不一样
neighbads
2020-11-24 07:22:50 +08:00
楼上大佬可能都没说到点子上,可以了解下 libffi 不但函数名可以运行时指定,连参数都可以。很多库和语言实现跨语言调用都是用的这个
Vibra
2020-11-24 10:33:39 +08:00
可是 C 是不支持反射的呀...
dzmcs
2020-11-24 10:59:21 +08:00
要么静态的指定函数指针表,要么动态加载。你用 switch 都可以,那就说明可以用函数指针的表,func 里 dispath

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/728485

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX