小编Iff*_*ffi的帖子

运行时动态函数解析

我的项目在运行时需要加载很多模块,每个模块都包含很多函数,形式类似于下面的伪代码:

void someFunction(Context &ctx) {
    bool result;
    result = ctx.call("someFunction2")(ctx.arg["arg1"], ctx.arg["arg2"])
             && ctx.call("someFunction3")(ctx.arg["arg1"], ctx.arg["arg3"]);
    ctx.result(result);
} 
Run Code Online (Sandbox Code Playgroud)

其中ctx.arg["arg1"]ctx.arg["arg2"]ctx.arg["arg3"]是传递到的参数someFunction在运行时。someFunction2并且someFunction3无法在编译时静态解析,但会在运行时在加载所有模块时知道(它们是否已在其他模块中定义)。

现在,一个简单的实现将使用散列映射来存储所有这些函数的函数句柄,但散列会很慢,因为通常需要搜索 10k 个函数,并且每个函数将在其他函数中被多次调用(例如:枚举参数以找到将产生所需结果的正确组合)。

因此,我正在寻找某种解决方案,它会在加载所有模块时对这些“ctx.call”执行一次替换,而不是每次都执行“散列和探测”。目前的主要问题是“替换”操作。我提出了一些想法,但它们并不完美:


第一个解决方案:创建一个内部函数inner_func(func_handle1, func_handle2, arg1, arg2, arg3),并用于std::bind创建一个外部包装器outer_wrapper()

问题:不是用户友好的,必须明确告诉上下文要查找哪些函数和参数。


第二种解决方案:使用元编程+ constexpr + 宏来自动统计函数和参数名称的引用,然后创建一个引用表,然后让上下文在运行时填充每个表。

问题:我无法解决,需要一些帮助。我已经阅读了来自 facebook、mpl 和 hana 的 Fatal 库的文档,但似乎没有一种干净的方法可以做到这一点。


第三种解决方案:使用 JIT 编译器

问题:c++ JIT 编译器的选择是有限的。NativeJIT 不够强大,easy::JIT 似乎不能定制,也不容易分发。asmjit 不可用。


PS:问题上下文是“自动规划器”,这些函数是用来构造谓词的。Context ctx只是一个例子,如果需要,您可以使用其他合适的语法,只要它们易于用于表示以下 lisp 表达式:

(and (at ?p ?c1)
(aircraft ?a)
(at …
Run Code Online (Sandbox Code Playgroud)

c++ templates jit metaprogramming

3
推荐指数
1
解决办法
291
查看次数

标签 统计

c++ ×1

jit ×1

metaprogramming ×1

templates ×1