C ++的脚本语言

时间:2010-06-30 14:54:54

标签: c++ scripting scripting-language

我在脚本语言方面有点生疏,只要它们最近像蘑菇一样突然出现:)

今天我认为有一种与C ++无缝对话的脚本语言会很好,也就是说,可以使用C ++类,对我来说最重要的是,可以编译成C ++或者一些DLL / .SO(加上它.h)以便我可以将它链接到我的C ++程序中并使用脚本定义或实现的类。

我知道我可以嵌入任何流行的脚本语言,如lua,ruby,python ......但是接口通常包含某种“eval”函数,用于评估提供的脚本代码。根据用于耦合C ++和脚本语言的工具,脚本回调到C ++的集成可能或多或少易于编写,但我没有看到任何实际上允许我编写独立模块的脚本语言作为.h和.so / dll暴露给我的程序(可能是生成C ++代码的脚本语言)。

你知道这样的工具/脚本语言吗?

提前致谢。

PD。我一直在思考Vala或Haskell的GHC。他们生成C,但不生成C ++ ......

10 个答案:

答案 0 :(得分:31)

以下是比语言绑定更多的C ++集成:

  • ChaiScript - 在一个小项目中尝试,有趣的是,这个是用C ++编写的,只需要包含一个标题!不确定它是否对一个大项目有好处,但会看到,试试它有一些品味!
  • Falcon - 尝试一个大项目,非常好;它不是ChaiScript的“一个包含嵌入”,但它是因为它非常灵活,并且完全被认为是在C ++中使用(在库中只有C ++代码) - 我决定坚持使用它来完成我需要大量工作的最大项目脚本灵活性(与ruby / python相当)
  • AngelScript - 尚未尝试
  • GameMonkey - 尚未尝试
  • Io - 尚未尝试

对于您来说,如果您真的想用C ++编写脚本模块并轻松地将其暴露给脚本语言,那么我建议使用Falcon 。它完全是用C ++编写的,所有模块/库都是这样编写的。

答案 1 :(得分:21)

在这个上下文中通常要问的问题是:如何公开我的C ++类,以便可以从脚本中实例化它们?答案通常类似于http://www.swig.org/

你问的是相反的问题,听起来你的问题有些复杂化了。生成.h文件和.so文件的脚本引擎实际上不是脚本引擎 - 它将是一个编译器!在这种情况下,您可以使用C ++。

脚本引擎不能像那样工作。您向它们传递一个脚本和一些回调,这些回调提供了一组可以从脚本调用的函数,引擎会解释该脚本。

答案 2 :(得分:21)

尝试lua:http://www.lua.org/

要在lua中使用C ++类,您可以使用:

要生成绑定,请使用tolua ++:http://www.codenix.com/~tolua/

它需要一个清理过的标题作为输入并输出一个c文件来完成这项工作。简单,美观,愉快。

为了在C ++中使用Lua对象,我采用的方法是使用(field,setField,callMethod,methods,fields)等方法编写通用的Proxy对象。

如果你想要一个dll,你可以将.lua作为资源(在Windows中,我不知道什么是Linux的合适等价物),并在你的DllMain上用lua代码初始化你的代理对象。

然后,c ++代码可以使用代理对象来调用lua代码,代理中可能会有一些内省方法来简化这项任务。

您可以为每个要编写的lua库重用代理对象,只需更改提供给它的lua代码即可。

答案 3 :(得分:13)

这略微超出了我的专业领域,但我愿意冒险投票。 : - )

Boost::Python似乎就是你要找的东西。它使用一些宏魔术来完成它的工作,但它确实将Python类暴露给C ++而不是干净利落。

答案 4 :(得分:5)

我是LikeMagic的作者,LikeMagic是Io语言的C ++绑定库。 (我不是Io的作者。)

http://github.com/dennisferron/LikeMagic

我对LikeMagic的一个明确目标是在两个方向上完整且完全的C ++互操作性。 LikeMagic将封装本地Io类型作为C ++类型(包括在STL容器和Io的本机List类型之间进行转换),它将代表Io中的C ++类,方法,字段和数组。您甚至可以传递Io环境的Io代码 out 块,并在C ++中将其用作仿函数!!

在Io脚本中包装C ++类型是简单,快速和简单的。从C ++访问脚本对象确实需要像您所描述的“eval”函数,但基于模板的类型转换和编组可以轻松访问执行脚本字符串的结果。上面提到的将Io block()对象转换为C ++仿函数的能力。

目前该项目仍处于早期阶段,尽管该项目已完全投入使用。我仍然需要做一些事情,比如记录它的构建步骤和依赖项,它只能用gcc 4.4.1+(不是Microsoft Visual C ++)构建,因为它使用了MSVC尚不支持的C ++ 0x功能。但是,它完全支持Linux和Windows,并计划使用Mac端口。

现在的坏消息:使脚本生成.h文件和.so或.dll文件可以从C ++调用,这不仅需要编译器(一种),但它也必须是 JIT编译器。这是因为(在许多脚本语言中,但最重要的是在Io中)对象的方法和字段直到运行时才知道 - 在Io中,甚至可以在实时对象中添加和删除方法!起初我会说,你要求这个事实让我想知道你是否真的不明白动态语言是什么。但我确实相信一种设计方式,在这种方式中,你首先想象一下理想的或最简单的做事方式,然后从那里向后工作到实际可行的方式。因此,我会从易于使用的角度承认,您所描述的内容听起来更容易使用。

虽然它是理想的,并且几乎不可能(使用带有JIT编译的脚本语言),但它不太实用,所以我仍然不确定你所要求的是你真正想要的。如果.h和.so / .dll文件是从脚本中进行了JIT,并且脚本发生了变化,那么您需要重新编译C ++程序以利用更改!这不是违反了首先使用脚本的主要好处吗?

唯一可行的方法是,如果界面定义的脚本没有改变,你只是为脚本函数制作C ++包装器。你最终会拥有很多C ++函数,如:

int get_foo() { return script.eval("get_foo()"); }
int get_bar() { return script.eval("get_bar()"); }

我会承认,从包装函数的调用者的角度来看,代码更清晰。但是,如果这就是你想要的,为什么不在脚本语言中使用反射并从脚本对象中存储的方法列表生成.h文件?这种反射可以是easily done in Io。在某些时候,我计划将OpenC++ source-to-source translator集成为LikeMagic中的可调用库,这意味着您甚至可以使用强大的C ++代码生成器而不是写出字符串。

答案 5 :(得分:2)

你可以用Lua做到这一点,但是如果你有很多类,你需要像SWIG或toLua ++这样的工具来为你生成一些粘合代码。

这些工具都不会处理您问题的异常部分,即隐藏脚本语言后面的.h文件,以及让您的C ++代码调用脚本而不知道脚本是什么。为此,您必须执行以下操作:

  • 自己编写胶水代码。 (对于Lua来说,这是相对简单的,直到你进入课程,因此它不是那么容易,这就是为什么存在像SWIG和toLua ++这样的工具的原因。)

  • 在界面后面隐藏脚本解释器的某种全局状态。

  • 假设您有多个.h文件,每个文件都是使用脚本实现的,您必须决定哪些文件以脚本语言共享状态,哪些文件使用不同的脚本编写状态。 (你基本上拥有的是用于脚本语言的VM,而极端的是(a)所有.h文件共同使用相同的VM,(b)每个.h文件都有自己独立的,独立的VM。其他选择更多复杂。)

如果您决定自己这样做,编写粘合代码将Lua表转换为C ++类(以便Lua代码看起来像C ++到程序的其余部分)是相当简单的。转向另一个方向,在Lua中包装C ++(以便C ++对象看起来像Lua值这样的脚本)是一个很大的麻烦。

无论你做什么,你都有一些工作要做。

答案 6 :(得分:1)

Google的V8 engine是用C ++编写的,我希望你能将它集成到一个项目中。他们谈论这样做in this article

答案 7 :(得分:1)

好问题,我自己经常想到这一点,但唉,这种事情没有简单的解决办法。如果您使用的是Windows(我猜不是),那么您可以通过在C ++和VB中创建COM组件(将其视为脚本语言)来实现这样的功能。通过COM接口进行交谈,这是在不同语言之间进行交互的好方法。同样适用于基于.NET的语言,它们之间可以互相作用。

我也非常想知道C ++是否存在类似的东西,最好是开源。

答案 8 :(得分:0)

您可以检查嵌入Guile(计划解释程序)或V8(Google的javascript解释程序 - 在Chrome中使用 - 用C ++编写)。

答案 9 :(得分:0)