使 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++ 应用程序可编写脚本的主要内容,如果未能解决你的问题,请参考以下文章

使用可编写脚本的应用程序向 Shelly 云发送请求

提供从 Siri 语音输入到可编写脚本或 pythonista 脚本的参数?

如何在 JavaScript 中继承 C++ 类?

Silverlight 数据绑定无法从可编写脚本的成员中工作

在可编写脚本的对象UNITY 5中存储方法

如何从统一自定义编辑器中的可编写脚本对象数组中获取值?