C++ 脚本语言
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/3150442/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Scripting language for C++
提问by Diego Sevilla
I'm getting a little rusty in scripting languages, provided they're popping like mushrooms lately :)
我对脚本语言有点生疏了,前提是它们最近像蘑菇一样流行:)
Today I thought that it would be nice to have a scripting language that talks seamlessly to C++, that is, could use C++ classes, and, the most important for me, could be compiled into C++ or some DLL/.SO (plus its .h) so that I could link it into my C++ program and make use of the classes the script defines or implements.
今天我认为拥有一种与 C++ 无缝对话的脚本语言会很好,也就是说,可以使用 C++ 类,而且,对我来说最重要的是,可以编译成 C++ 或一些 DLL/.SO(加上它的 . h) 这样我就可以将它链接到我的 C++ 程序中并使用脚本定义或实现的类。
I know I could embed any popular scripting language such as lua, ruby, python... but the interface usually includes some kind of "eval" function that evaluates the provided scripting code. Depending on the tool used to couple C++ and the scripting language, the integration for callbacks of the script into C++ could be more or less easy to write, but I haven't seen any scripting language that actually allows me to write independent modules that are exposed as a .h and .so/dll to my program (maybe along the lines of a scripting language that generates C++ code).
我知道我可以嵌入任何流行的脚本语言,例如 lua、ruby、python……但接口通常包含某种“eval”函数来评估提供的脚本代码。根据用于耦合 C++ 和脚本语言的工具,将脚本回调集成到 C++ 中可能或多或少容易编写,但我还没有看到任何脚本语言实际上允许我编写独立的模块作为 .h 和 .so/dll 公开给我的程序(可能沿着生成 C++ 代码的脚本语言的路线)。
Do you know any such tool/scripting language?
你知道任何这样的工具/脚本语言吗?
Thanks in advance.
提前致谢。
PD. I've been thinking along the lines of Valaor Haskell's GHC. They generate C, but not C++...
PD。我一直在思考Vala或 Haskell 的 GHC。它们生成 C,但不生成 C++...
回答by Klaim
UPDATE 2020: Today I would probably go with Lua + Sol2/3except if I really want to avoid Lua as a language. Chaiscript becomes a good candidate in this case though it is not optimal performance-wise compared to Lua+Sol2/3 (though it was greatly improved through years so it is still good enough in many cases). Falcon have been dead for some years, RIP.
2020 年更新:今天我可能会使用 Lua + Sol2/3,除非我真的想避免将 Lua 作为一种语言。Chaiscript 在这种情况下成为一个很好的候选者,尽管与 Lua+Sol2/3 相比它在性能方面不是最佳的(尽管多年来它已经有了很大的改进,所以在许多情况下它仍然足够好)。猎鹰已经死了好几年了,RIP。
The following ones are more C++ integration oriented than language bindings :
以下是比语言绑定更面向 C++ 集成的:
- ChaiScript- trying at the moment in a little project, interesting, this one is MADE with C++ in mind and works by just including a header! Not sure if it's good for a big project yet but will see, try it to have some taste!
- (not maintained anymore)Falcon- trying on a big project, excellent; it's not a "one include embed" as ChaiScript but it's because it's really flexible, and totally thought to be used in C++ (only C++ code in libs) - I've decided to stick with it for my biggest project that require a lot of scripting flexibility (comparable to ruby/python )
- AngelScript- didn't try yet
- GameMonkey- didn't try yet
- Io- didn't try yet
- ChaiScript- 目前正在一个小项目中尝试,有趣的是,这个是用 C++ 制作的,只需包含一个标题就可以工作!不确定它是否适合一个大项目,但会看到,尝试一下吧!
- (不再维护)Falcon- 尝试一个大项目,非常好;它不是像 ChaiScript 那样的“一个包含嵌入”,而是因为它非常灵活,并且完全被认为可以在 C++ 中使用(libs 中只有 C++ 代码)——我决定在我最大的项目中坚持使用它,需要很多脚本灵活性(与 ruby/python 相当)
- AngelScript- 还没试过
- GameMonkey- 还没试过
- Io- 还没试过
For you, if you really want to write your scripting module in C++ and easily expose it to the scripting language, I would recommand going with Falcon. It's totally MADE in C++, all the modules/libraries are written that way.
对您而言,如果您真的想用 C++ 编写脚本模块并轻松将其公开给脚本语言,我建议您使用 Falcon。它完全是用 C++ 制作的,所有的模块/库都是这样编写的。
回答by Daniel Earwicker
The question usually asked in this context is: how do I expose my C++ classes so they can be instantiated from script? And the answer is often something like http://www.swig.org/
在这种情况下通常会问的问题是:如何公开我的 C++ 类,以便它们可以从脚本中实例化?答案通常类似于http://www.swig.org/
You're asking the opposite question and it sounds like you're complicating matters a bit. A scripting engine that produced .h files and .so files wouldn't really be a scripting engine - it would be a compiler! In which case you could use C++.
你问的是相反的问题,听起来你把事情复杂化了一点。生成 .h 文件和 .so 文件的脚本引擎并不是真正的脚本引擎——而是编译器!在这种情况下,您可以使用 C++。
Scripting engines don't work like that. You pass them a script and some callbacks that provide a set of functions that can be called from the script, and the engine interprets the script.
脚本引擎不是这样工作的。你向他们传递一个脚本和一些回调函数,这些回调函数提供了一组可以从脚本调用的函数,然后引擎解释脚本。
回答by Vitor Py
Try lua: http://www.lua.org/
试试 lua:http: //www.lua.org/
For using C++ classes in lua you can use:
要在 lua 中使用 C++ 类,您可以使用:
To generate binding use tolua++: http://www.codenix.com/~tolua/
要生成绑定使用 tolua++:http: //www.codenix.com/~tolua/
It takes a cleaned up header as input and outputs a c file that does the hard work. Easy, nice and a pleasure to work with.
它需要一个清理过的头作为输入并输出完成艰苦工作的 ac 文件。轻松,愉快,合作愉快。
For using Lua objects in C++ I'd take the approach of writing a generic Proxy object with methods like (field, setField, callMethod, methods, fields).
为了在 C++ 中使用 Lua 对象,我会采用使用(字段、setField、callMethod、方法、字段)等方法编写通用代理对象的方法。
If you want a dll you could have the .lua as a resource (in Windows, I don't know what could be a suitable equivalent for Linux) and on your DllMain initialize your proxy object with the lua code.
如果您想要一个 dll,您可以将 .lua 作为资源(在 Windows 中,我不知道什么可能适合 Linux)并在您的 DllMain 上使用 lua 代码初始化您的代理对象。
The c++ code can then use the proxy object to call the lua code, with maybe a few introspection methods in the proxy to make this task easier.
然后,c++ 代码可以使用代理对象来调用 lua 代码,可能在代理中使用一些自省方法来简化此任务。
You could just reuse the proxy object for every lua library you want to write, just changing the lua code provided to it.
您可以为要编写的每个 lua 库重用代理对象,只需更改提供给它的 lua 代码。
回答by Dragontamer5788
This is slightly outside my area of expertise, but I'm willing to risk the downvotes. :-)
这稍微超出了我的专业领域,但我愿意冒险投反对票。:-)
Boost::Pythonseems to be what you're looking for. It uses a bit of macro magic to do its stuff, but it does expose Python classes to C++ rather cleanly.
Boost::Python似乎就是你要找的东西。它使用了一些宏魔法来完成它的工作,但它确实相当干净地将 Python 类公开给 C++。
回答by Dennis
I'm the author of LikeMagic, a C++ binding library for the Io language. (I am not the author of Io.)
我是 LikeMagic 的作者,LikeMagic 是 Io 语言的 C++ 绑定库。(我不是 Io 的作者。)
http://github.com/dennisferron/LikeMagic
http://github.com/dennisferron/LikeMagic
One of my explicit goals with LikeMagic is complete and total C++ interoperability, in both directions. LikeMagic will marshal native Io types as C++ types (including converting between STL containers and Io's native List type) and it will represent C++ classes, methods, fields, and arrays within Io. You can even pass a block of Io code outof the Io environment and use it in C++ as a functor!!
我对 LikeMagic 的明确目标之一是在两个方向上实现完全和完全的 C++ 互操作性。LikeMagic 会将原生 Io 类型编组为 C++ 类型(包括在 STL 容器和 Io 的原生 List 类型之间进行转换),并且它将表示 Io 中的 C++ 类、方法、字段和数组。您甚至可以将 Io 代码块从Io 环境中传递出来,并在 C++ 中用作函子!
Wrapping C++ types up for consumption in Io script is simple, quick and easy. Accessing script objects from C++ does require an "eval" function like you described, but the template based type conversion and marshaling makes it easy to access the result of executing a script string. And there is the aforementioned ability to turn Io block() objects into C++ functors.
在 Io 脚本中包装 C++ 类型以供使用非常简单、快速和容易。从 C++ 访问脚本对象确实需要像您描述的那样的“eval”函数,但是基于模板的类型转换和封送处理可以轻松访问执行脚本字符串的结果。还有前面提到的将 Io block() 对象转换为 C++ 函子的能力。
Right now the project is still in the early stages, although it is fully operational. I still need to do things like document its build steps and dependencies, and it can only be built with gcc 4.4.1+ (not Microsoft Visual C++) because it uses C++0x features not yet supported in MSVC. However, it does fully support Linux and Windows, and a Mac port is planned.
目前,该项目仍处于早期阶段,但已全面投入运营。我仍然需要做一些事情,比如记录它的构建步骤和依赖项,它只能用 gcc 4.4.1+(不是 Microsoft Visual C++)构建,因为它使用了 MSVC 尚不支持的 C++0x 功能。但是,它确实完全支持 Linux 和 Windows,并且计划了一个 Mac 端口。
Now the bad news: Making the scripts produce .h files and .so or .dll files callable from C++ would not only require a compiler(of a sort) but it would also have to be a JIT compiler. That's because (in many scripting languages, but most especially in Io) an object's methods and fields are not known until runtime - and in Io, methods can even be added and removed from live objects! At first I was going to say that the very fact that you're asking for this makes me wonder if perhaps you don't really understand what a dynamic language is. But I do believe in a way of design in which you first try to imagine the ideal or easiest possible way of doing something, and then work backwards from there to what is actually possible. And so I'll admit from an ease-of-use standpoint, what you describe sounds easier to use.
现在坏消息是:使脚本生成可从 C++ 调用的 .h 文件和 .so 或 .dll 文件不仅需要编译器(某种),而且还必须是JIT 编译器。这是因为(在许多脚本语言中,尤其是在 Io 中)直到运行时才知道对象的方法和字段 - 在 Io 中,甚至可以从活动对象中添加和删除方法!起初我想说的是,你要求这样做的事实让我怀疑你是否真的不理解动态语言是什么. 但我确实相信一种设计方式,在这种设计方式中,您首先尝试想象做某事的理想或最简单的可能方式,然后从那里倒退到实际可行的方式。所以我会从易用性的角度承认,你所描述的听起来更容易使用。
But while it's ideal, and just barely possible (using a script language with JIT compilation), it isn't very practical, so I'm still unsure if what you're asking for is what you really want. If the .h and .so/.dll files are JITted from the script, and the script changes, you'd need to recompile your C++ program to take advantage of the change! Doesn't that violate the main benefit of using script in the first place?
但是,虽然它是理想的,而且几乎不可能(使用带有 JIT 编译的脚本语言),但它不是很实用,所以我仍然不确定您所要求的是否是您真正想要的。如果 .h 和 .so/.dll 文件是从脚本中 JITted 的,并且脚本发生了变化,则您需要重新编译 C++ 程序以利用更改!这不是首先违反了使用脚本的主要好处吗?
The only way it is practical would be if the interfaces defined the scripts do not change, and you just are making C++ wrappers for script functions. You'd end up having a lot of C++ functions like:
唯一可行的方法是,如果定义脚本的接口不改变,而您只是为脚本函数制作 C++ 包装器。你最终会得到很多 C++ 函数,比如:
int get_foo() { return script.eval("get_foo()"); }
int get_bar() { return script.eval("get_bar()"); }
I will admit that's cleaner looking code from the point of view of the callers of the wrapper function. But if that's what you want, why not just use reflection in the scripting language and generate a .h file off of the method lists stored in the script objects? This kind of reflection can be easily done in Io. At some point I plan to integrate the OpenC++ source-to-source translatoras a callable library from LikeMagic, which means you could even use a robust C++ code generator instead of writing out strings.
我承认,从包装函数的调用者的角度来看,这是更清晰的代码。但是,如果这就是您想要的,为什么不直接在脚本语言中使用反射并从存储在脚本对象中的方法列表中生成一个 .h 文件呢?这种反射可以在 Io 中轻松完成。在某个时候,我计划将OpenC++ 源代码到源代码转换器集成为来自 LikeMagic 的可调用库,这意味着您甚至可以使用强大的 C++ 代码生成器而不是写出字符串。
回答by Norman Ramsey
You can do this with Lua, but if you have a lot of classes you'll want a tool like SWIG or toLua++ to generate some of the glue code for you.
你可以用 Lua 做到这一点,但如果你有很多类,你需要一个像 SWIG 或 toLua++ 这样的工具来为你生成一些胶水代码。
None of these tools will handle the unusual part of your problem, which is to have a .h file behind which is hidden a scripting language, and to have your C++ code call scripts without knowing that that are scripts. To accomplish this, you will have to do the following:
这些工具都不会处理您的问题的不寻常部分,即在其背后隐藏脚本语言的 .h 文件,并让您的 C++ 代码调用脚本而不知道那是脚本。为此,您必须执行以下操作:
Write the glue code yourself. (For Lua, this is relatively easy, until you get into classes, whereupon it's not so easy, which is why tools like SWIG and toLua++ exist.)
Hide behind the interface some kind of global state of the scripting interpreter.
Supposing you have multiple .h files that each are implemented using scripts, you have to decide which ones share state in the scripting languageand which ones use separate scripting states. (What you basically have is a VM for the scripting language, and the extremes are (a) all .h files use the same VM in common and (b) each .h file has its own separate, isolated VM. Other choices are more complicated.)
自己写胶水代码。(对于 Lua 来说,这相对容易,直到你进入类,然后才不是那么容易,这就是为什么像 SWIG 和 toLua++ 这样的工具存在的原因。)
在接口后面隐藏脚本解释器的某种全局状态。
假设您有多个 .h 文件,每个文件都使用脚本实现,您必须决定哪些文件在脚本语言中共享状态,哪些使用单独的脚本状态。(您基本上拥有的是一个用于脚本语言的虚拟机,极端情况是(a)所有 .h 文件都使用相同的虚拟机,并且(b)每个 .h 文件都有自己独立的、隔离的虚拟机。其他选择更多复杂的。)
If you decide to do this yourself, writing the glue code to turn Lua tables into C++ classes (so that Lua code looks like C++ to the rest of the program) is fairly straightforward. Going in the other direction, where you wrap your C++ in Lua (so that C++ objects look to the scripts like Lua values) is a big pain in the ass.
如果您决定自己这样做,编写粘合代码将 Lua 表转换为 C++ 类(这样 Lua 代码在程序的其余部分看起来像 C++)是相当简单的。在另一个方向上,将 C++ 包装在 Lua 中(以便 C++ 对象看起来像 Lua 值一样的脚本)是一个很大的麻烦。
No matter what you do, you have some work ahead of you.
不管你做什么,你都有一些工作要做。
回答by tathagata
Good question, I have often thought about this myself, but alas there is no easy solution to this kind of thing. If you are on Windows (I guess not), then you could achieve something like this by creating COM components in C++ and VB (considering that as a scripting language). The talking happens through COM interfaces, which is a nice way to interop between disparate languages. Same holds for .NET based languages which can interop between themselves.
好问题,我自己也经常考虑这个问题,但唉,这种事情没有简单的解决方案。如果您使用的是 Windows(我猜不是),那么您可以通过在 C++ 和 VB 中创建 COM 组件(将其视为一种脚本语言)来实现类似的功能。对话是通过 COM 接口进行的,这是一种在不同语言之间进行互操作的好方法。同样适用于基于 .NET 的语言,它们可以在它们之间进行互操作。
I too am eager to know if something like this exists for C++, preferably open source.
我也很想知道 C++ 是否存在这样的东西,最好是开源的。
回答by T.J. Crowder
Google's V8 engineis written in C++, I expect you might be able to integrate it into a project. They talk about doing that in this article.
回答by Ben Collins
回答by msfclipper
Try the Ring programming language http://ring-lang.net
尝试 Ring 编程语言 http://ring-lang.net
(1) Extension using the C/C++ languages https://en.wikibooks.org/wiki/Ring/Lessons/Extension_using_the_C/C%2B%2B_languages
(1) 使用 C/C++ 语言的扩展 https://en.wikibooks.org/wiki/Ring/Lessons/Extension_using_the_C/C%2B%2B_languages
(2) Embedding Ring Interpreter in C/C++ Programs https://en.wikibooks.org/wiki/Ring/Lessons/Embedding_Ring_Interpreter_in_C/C%2B%2B_Programs
(2) 在 C/C++ 程序中嵌入 Ring Interpreter https://en.wikibooks.org/wiki/Ring/Lessons/Embedding_Ring_Interpreter_in_C/C%2B%2B_Programs
(3) Code Generator for wrapping C/C++ Libraries https://en.wikibooks.org/wiki/Ring/Lessons/Code_Generator_for_wrapping_C/C%2B%2B_Libraries
(3) 用于包装 C/C++ 库的代码生成器 https://en.wikibooks.org/wiki/Ring/Lessons/Code_Generator_for_wrapping_C/C%2B%2B_Libraries