V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
HHPLow
V2EX  ›  C

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

  •  
  •   HHPLow · 2020-11-23 20:51:03 +08:00 · 2777 次点击
    这是一个创建于 632 天前的主题,其中的信息可能已经有所发展或是发生改变。

    有两个函数的参数 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 20:54:40 +08:00   ❤️ 3
    我觉得你连需求都没描述清楚……

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

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

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

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

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

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

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

    或许是你想实现的。
    no1xsyzy
        12
    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
        13
    GeruzoniAnsasu  
       2020-11-24 01:40:22 +08:00
    dlopen dlsym
    loadlibrary getprocessaddress


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

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

    http 服务的路由也是这个啊,识别 uri,然后调用对应的方法去处理请求。 方向都差不多,只是实现细节不一样
    neighbads
        17
    neighbads  
       2020-11-24 07:22:50 +08:00 via Android
    楼上大佬可能都没说到点子上,可以了解下 libffi 不但函数名可以运行时指定,连参数都可以。很多库和语言实现跨语言调用都是用的这个
    Vibra
        18
    Vibra  
       2020-11-24 10:33:39 +08:00
    可是 C 是不支持反射的呀...
    dzmcs
        19
    dzmcs  
       2020-11-24 10:59:21 +08:00
    要么静态的指定函数指针表,要么动态加载。你用 switch 都可以,那就说明可以用函数指针的表,func 里 dispath
    关于   ·   帮助文档   ·   API   ·   FAQ   ·   我们的愿景   ·   广告投放   ·   感谢   ·   实用小工具   ·   1169 人在线   最高记录 5497   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 188ms · UTC 20:11 · PVG 04:11 · LAX 13:11 · JFK 16:11
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.