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

2019-09-02 12:12:00 +08:00
 fyyz

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

举例:

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)>> 对象,但是这种方法会使得注册函数比较容易遗漏。

5170 次点击
所在节点    C++
13 条回复
whileFalse
2019-09-02 12:20:37 +08:00
不会啊。你只需要:


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

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

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

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

具体参考 man dlopen

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

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

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

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

© 2021 V2EX