偷懒是人类进步的阶梯,请问大佬们 C 如何运行时生成函数指针 - V2EX
V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
HHPLow
V2EX    C

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

  •  
  •   HHPLow 2020 年 11 月 23 日 4141 次点击
    这是一个创建于 1956 天前的主题,其中的信息可能已经有所发展或是发生改变。

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

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

    19 条回复    2020-11-24 10:59:21 +08:00
    lcdtyph
        1
    lcdtyph  
       2020 年 11 月 23 日   3
    我觉得你连需求都没描述清楚……

    盲建议个跳转表吧
    Ediacaran
        2
    Ediacaran  
       2020 年 11 月 23 日 via iPhone
    想要柯里化还是闭包?

    C 里面都没有常规能实现的方法
    Tony042
        4
    Tony042  
       2020 年 11 月 23 日
    函数重载?
    HHPLow
        5
    HHPLow  
    OP
       2020 年 11 月 23 日 via iPhone
    @ETiV 多谢!之前不明白反射是个啥现在知道了

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

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

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

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

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

    或许是你想实现的。
    no1xsyzy
        12
    no1xsyzy  
       2020 年 11 月 24 日
    根据参数修改实际调用函数?
    这个 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
        13
    GeruzoniAnsasu  
       2020 年 11 月 24 日
    dlopen dlsym
    loadlibrary getprocessaddress


    “运行时获得函数地址” 只有这种办法
    其它的都只是编译期把地址存到固定地方而已
    felixin
        14
    felixin  
       2020 年 11 月 24 日 via Android
    这就是多态,触摸到软件工程的边了
    GeruzoniAnsasu
        15
    GeruzoniAnsasu  
       2020 年 11 月 24 日
    *getprocaddress

    或者可以用宏来自动给新加的函数增加额外注册逻辑
    Maboroshii
        16
    Maboroshii  
       2020 年 11 月 24 日
    写一个脚本来生成初始化的部分就省事了吧。

    http 服务的路由也是这个啊,识别 uri,然后调用对应的方法去处理请求。 方向都差不多,只是实现细节不一样
    neighbads
        17
    neighbads  
       2020 年 11 月 24 日 via Android
    楼上大佬可能都没说到点子上,可以了解下 libffi 不但函数名可以运行时指定,连参数都可以。很多库和语言实现跨语言调用都是用的这个
    Vibra
        18
    Vibra  
       2020 年 11 月 24 日
    可是 C 是不支持反射的呀...
    dzmcs
        19
    dzmcs  
       2020 年 11 月 24 日
    要么静态的指定函数指针表,要么动态加载。你用 switch 都可以,那就说明可以用函数指针的表,func 里 dispath
    关于     帮助文档     自助推广系统     博客     API     FAQ     Solana     5695 人在线   最高记录 6679       Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 29ms UTC 03:07 PVG 11:07 LAX 20:07 JFK 23:07
    Do have faith in what you're doing.
    ubao msn snddm index pchome yahoo rakuten mypaper meadowduck bidyahoo youbao zxmzxm asda bnvcg cvbfg dfscv mmhjk xxddc yybgb zznbn ccubao uaitu acv GXCV ET GDG YH FG BCVB FJFH CBRE CBC GDG ET54 WRWR RWER WREW WRWER RWER SDG EW SF DSFSF fbbs ubao fhd dfg ewr dg df ewwr ewwr et ruyut utut dfg fgd gdfgt etg dfgt dfgd ert4 gd fgg wr 235 wer3 we vsdf sdf gdf ert xcv sdf rwer hfd dfg cvb rwf afb dfh jgh bmn lgh rty gfds cxv xcv xcs vdas fdf fgd cv sdf tert sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf shasha9178 shasha9178 shasha9178 shasha9178 shasha9178 liflif2 liflif2 liflif2 liflif2 liflif2 liblib3 liblib3 liblib3 liblib3 liblib3 zhazha444 zhazha444 zhazha444 zhazha444 zhazha444 dende5 dende denden denden2 denden21 fenfen9 fenf619 fen619 fenfe9 fe619 sdf sdf sdf sdf sdf zhazh90 zhazh0 zhaa50 zha90 zh590 zho zhoz zhozh zhozho zhozho2 lislis lls95 lili95 lils5 liss9 sdf0ty987 sdft876 sdft9876 sdf09876 sd0t9876 sdf0ty98 sdf0976 sdf0ty986 sdf0ty96 sdf0t76 sdf0876 df0ty98 sf0t876 sd0ty76 sdy76 sdf76 sdf0t76 sdf0ty9 sdf0ty98 sdf0ty987 sdf0ty98 sdf6676 sdf876 sd876 sd876 sdf6 sdf6 sdf9876 sdf0t sdf06 sdf0ty9776 sdf0ty9776 sdf0ty76 sdf8876 sdf0t sd6 sdf06 s688876 sd688 sdf86