使 C++ 应用程序可编写脚本
Posted
技术标签:
【中文标题】使 C++ 应用程序可编写脚本【英文标题】:Making a C++ app scriptable 【发布时间】:2009-01-28 12:17:50 【问题描述】:我的程序中有几个函数如下所示:
void foo(int x, int y)
现在我希望我的程序采用如下所示的字符串:
foo(3, 5)
并执行相应的功能。最直接的实现方式是什么?
当我说直截了当时,我的意思是可合理扩展和优雅,但编写代码应该不会花费太长时间。
编辑:
虽然使用真正的脚本语言当然可以解决我的问题,但我仍然想知道是否有一种快速的方法可以在纯 C++ 中实现这一点。
【问题讨论】:
【参考方案1】:您可以相当简单地嵌入 Python,这将为您提供一种非常强大、可扩展的方式来编写程序脚本。您可以使用以下内容轻松(或多或少)将您的 C++ 代码公开给 Python:
Boost Python SWIG我个人使用 Boost Python,对此我很满意,但它编译速度很慢,而且可能难以调试。
【讨论】:
【参考方案2】:你可以看看Lua。
【讨论】:
看看 Lua - 做什么???该页面几乎无法描述如何嵌入语言。甚至手册的第 3 页 (lua.org/manual/5.1/manual.html#3) 更接近但对 OP 没有帮助。 “使用 lua”正在成为对类似问题的下意识反应。【参考方案3】:我也会选择脚本语言的答案。
使用纯 C++,我可能会使用解析器生成器,它将获取标记和语法规则,并为我提供完全可以解析给定函数调用语言的 C 代码,并为我提供该语法树称呼。 flex
可用于标记输入,bison
可用于解析标记并将其转换为语法树。作为该方法的替代方案,Boost Spirit 也可用于解析函数调用语言。我从未使用过这些工具中的任何一个,但曾开发过使用它们的程序,因此我有点知道在必须解决该问题时我会使用什么。
对于非常简单的情况,您可以将语法更改为:
func_name arg1, arg2
那么你可以使用:
std::istringstream str(line);
std::string fun_name; str >> fun_name;
map[fun_name](tokenize_args(str));
地图将是一个
std::map<std::string, boost::function<void(std::vector<std::string>)> > map;
它将在程序开始时填充函数。 tokenize_args
只会分离参数,并将它们的向量作为字符串返回。当然,这是非常原始的,但我认为如果你想要的只是某种调用函数的方法是合理的(当然,如果你想要真正的脚本支持,这种方法是不够的)。
【讨论】:
我会选择 boost::spirit,因为你会学到很多关于解析器和模板元编程的知识。【参考方案4】:正如丹尼尔所说:
Lua 和 Python 等脚本语言将是最常用的用于将 c++ 库绑定在一起的脚本语言。
您必须向您的 c++ 应用程序添加一个脚本接口。这个界面的构建显然取决于您选择的脚本语言。
【讨论】:
【参考方案5】:CERN 提供 CINT,这是一个 C/C++ 解释器,可以嵌入到您的应用程序中以提供脚本功能。
【讨论】:
【参考方案6】:如果您只想通过字面名称调用函数,则可以使用链接器特定的函数。
在 POSIX 兼容的操作系统(如 Linux)上,您可以使用 dlopen() 和 dlsym()。您只需解析输入字符串并找出函数名称和参数。然后,您可以要求链接器使用 dlsym() 按名称查找函数。
但是,在 Windows 上,这些功能不可用(除非周围有一些 POSIX 环境,例如 Cygwin)。但您可以使用 Windows API。
您可以在此处查看有关这些内容的详细信息:http://en.wikipedia.org/wiki/Dynamic_loading
【讨论】:
【参考方案7】:Fabio Lombardelli 的 C++ Reflection [2] 通过模板元编程技术为 C++ 提供了完整的反思。虽然它完全符合 C++ 标准,但它需要程序员对类进行注释以使其具有反射性
http://cppreflect.sourceforge.net/
否则我想你会想要一个函数指针哈希表
【讨论】:
【参考方案8】:您的系统是否必须“接受字符串”?您可以在您的应用程序上公开 COM(或 CORBA 或其他)接口,并让生成这些命令的任何内容直接调用您的应用程序。
【讨论】:
以上是关于使 C++ 应用程序可编写脚本的主要内容,如果未能解决你的问题,请参考以下文章
提供从 Siri 语音输入到可编写脚本或 pythonista 脚本的参数?