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

C++ 如何才能“从字符串找到同名函数”这种反射?

  •  
  •   fyyz · 2019-09-02 12:12:00 +08:00 · 5431 次点击
    这是一个创建于 1934 天前的主题,其中的信息可能已经有所发展或是发生改变。

    现在希望实现一个需求,就是用户可以直接在配置文件中调整调用函数的顺序,我的程序能立刻根据配置文件中的定义来执行对应的操作顺序。

    举例:

    C++文件:

    void f1(){cout<<"f1";}
    void f2(){cout<<"f2";}
    void f3(){cout<<"f3";}
    

    配置文件:

    <event event_="Add">
    	<handle>f3</handle>
    	<handle>f2</handle>
    	<handle>f1</handle>
    </event>
    

    那么执行程序,当 Add 事件被触发就会依次输出 f3 f2 f1。

    这种需求有什么好的方法实现吗?

    我能想到的方法是,构建一个 map<string,function<void(void)>> 对象,但是这种方法会使得注册函数比较容易遗漏。

    13 条回复    2019-09-03 17:35:31 +08:00
    whileFalse
        1
    whileFalse  
       2019-09-02 12:20:37 +08:00
    不会啊。你只需要:


    以任何方式使用这一系列函数时,都只通过你这个“注册中心”调用,绝对不直接调用函数名。
    这样如果你写了一个函数但没有把它放到注册中心里,就跟没写一样,所以你肯定会发现的。
    nifury
        2
    nifury  
       2019-09-02 12:21:06 +08:00
    做成导出函数?
    不过一样会有遗漏的问题

    原生函数不加修饰的话函数名信息肯定没有了
    加的话就会有遗漏的问题
    感觉无解
    joshu
        3
    joshu  
       2019-09-02 12:24:04 +08:00 via Android   ❤️ 1
    我觉得就只有这种方法吧。。。如果函数签名不一样就用函数指针吧,写个宏封装参数形态和名称注册
    AlohaV2
        4
    AlohaV2  
       2019-09-02 12:40:28 +08:00 via iPhone
    保证接口一致,然后用静态的 map 注册好函数名到函数的对应,比如是 string 到 std function<void()>.
    GeruzoniAnsasu
        5
    GeruzoniAnsasu  
       2019-09-02 12:52:37 +08:00 via Android
    不清楚具体需求

    但给个思路:不考虑移植性的话,函数名可以通过 dladdr 查到,再通过 abi::__cxa_demangle 转成可读的签名
    ai277014717
        7
    ai277014717  
       2019-09-02 12:58:13 +08:00
    commit 加个钩子检查一下配置文件和类的关系
    Yang2096
        8
    Yang2096  
       2019-09-02 13:00:04 +08:00 via Android
    有点责任链模式的感觉,不知道行不行
    x1314aq
        9
    x1314aq  
       2019-09-02 13:05:40 +08:00 via iPhone
    直接通过 dlsym()就可以拿到函数地址,不需要其他别的任何操作。
    skywolf1219
        10
    skywolf1219  
       2019-09-02 13:09:32 +08:00
    推荐一个 c++的反射库
    https://www.rttr.org/
    ChristopherWu
        11
    ChristopherWu  
       2019-09-02 13:26:38 +08:00
    请看: https://github.com/YongHaoWu/C_eval

    直接读符号表获取函数指针
    zacharyjia
        12
    zacharyjia  
       2019-09-02 13:57:17 +08:00
    @x1314aq dlsym 只能用在动态链接库里吧,有通用的办法吗?
    x1314aq
        13
    x1314aq  
       2019-09-03 17:35:31 +08:00 via iPhone
    @zacharyjia #12 不只针对动态库,对当前可执行文件也适用的,第一个参数传 NULL 即可;

    具体参考 man dlopen
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   5348 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 26ms · UTC 08:17 · PVG 16:17 · LAX 00:17 · JFK 03:17
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.