Scripting language for C++ [closed]
Asked Answered
B

10

41

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.

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).

Do you know any such tool/scripting language?

Thanks in advance.

PD. I've been thinking along the lines of Vala or Haskell's GHC. They generate C, but not C++...

Bulganin answered 30/6, 2010 at 14:54 Comment(3)
The question seems not to be off-topic to me.Leucopoiesis
Sorry, but why would you use a scripting language? What else does it provide other than user input?Percaline
@DiegoSevilla another programming language has born. Is called ZetScript I don't know if you are looking for script engine yet but take a look just in case it fits your needs! zetscript.orgVaucluse
R
35

UPDATE 2020: Today I would probably go with Lua + Sol2/3 except 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.


The following ones are more C++ integration oriented than language bindings :

  • 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

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.

Retarded answered 30/6, 2010 at 21:10 Comment(7)
Thanks, Klaim. This is the kind of answer I was looking for. I'm going to try your recommendations and let's see.Bulganin
No problem, I've done a lot of searching (with help on forums) to get this list of interesting scripting languages.Retarded
@DiegoSevilla Hey, did you try those languages and did I answer your question correctly? :)Retarded
@DiegoSevilla I think I will just get here again every 2 years until you validate my answer XDRetarded
Haha,funny, but still I think it hasn't been invented... :( ClojureC is near, ECL and Chicken Scheme are also in that direction... I'll check again...Bulganin
@DiegoSevilla Do you mean that ChaiScript don't match your needs? O__o Or not even Falcon? (which is in the middle of a massive new engine release by the way, they are currently designing the new embedding interface)Retarded
Now a secondary question. Which of these languages look more like C++ themselves. (Is that desirable?)Deliverance
S
21

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/

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++.

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.

Slice answered 30/6, 2010 at 15:1 Comment(2)
Daniel, yes, scripting engines may do dynamic execution, but they may not. Maybe what I'm looking for, as I stated, is a scripting language instead of a scripting engine. Along the lines of GNOME's Vala, more an aid for writing fast code that it is converted to C++ (C in the case of Vala), or like ghc, that actually generates C code taking into account garbage collection, etc. It would be kind of a DSL for C++ that also has a run-time set of libraries that can be used. Maybe the google go language is the answer (curiously not mentioned by anyone)...Bulganin
Maybe because Go, like Lua and other languages, interfaces with C but not directly with C++... source : golang.org/doc/…Retarded
C
21

Try lua: http://www.lua.org/

For using C++ classes in lua you can use:

To generate binding use 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.

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).

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.

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.

You could just reuse the proxy object for every lua library you want to write, just changing the lua code provided to it.

Claudineclaudio answered 30/6, 2010 at 15:21 Comment(3)
The link is dead.......Demoniac
@RanWang That's a 7 year old answer. It's been a while since I've used tolua++. Googling for 'tolua++' shows a few GitHub repos - does any of them works for you?Claudineclaudio
Found it~ Thank you very muchDemoniac
T
12

This is slightly outside my area of expertise, but I'm willing to risk the downvotes. :-)

Boost::Python seems 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.

Todhunter answered 30/6, 2010 at 14:59 Comment(1)
My experience with Boost:Python was unhappy. The code also appeared to be rotting on the vine. SWIG was a much better experience.Milestone
F
5

I'm the author of LikeMagic, a C++ binding library for the Io language. (I am not the author of Io.)

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 out of the Io environment and use it in C++ as a functor!!

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.

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.

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.

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?

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:

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 translator as a callable library from LikeMagic, which means you could even use a robust C++ code generator instead of writing out strings.

Floria answered 30/6, 2010 at 22:52 Comment(0)
R
2

Google's V8 engine is written in C++, I expect you might be able to integrate it into a project. They talk about doing that in this article.

Riata answered 30/6, 2010 at 14:57 Comment(2)
Oh, no, not embeeding, but that the scripting language be able to generate stand-alone .so modules (and the corresponding .h files to be used from C++)Bulganin
@Diego: Well, I expect you could wrap up some JavaScript code and the V8 interpreter into an .so :-) but I doubt that's what you mean. So, something that compiles JavaScript to machine code (rather than allowing JavaScript to talk seamlessly to C++) and does away with the garbage collector (probably by using reference counting instead) and other aspects of the interpreter. It's a tall order. V8 does compile JavaScript directly to machine code, but on-the-fly and in a dynamic way (because JavaScript is a dynamic language). Never heard of one for C++. [OT: There is one for Java (Rhino).]Riata
C
2

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.

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:

  • 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 language and 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.)

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.

No matter what you do, you have some work ahead of you.

Crumpton answered 30/6, 2010 at 20:34 Comment(0)
P
1

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.

I too am eager to know if something like this exists for C++, preferably open source.

Premundane answered 30/6, 2010 at 15:9 Comment(2)
"which is a nice way to interop ..." : I have to strongly disagree. COM (especially when used to interface VB and C++) is particularly difficult to use...Marni
Okay, yes, COM interop has several quirks :), when used between C++ and VB, and maybe more so when between .NET and COM; you have thoroughly understand and memorized a lot of it, not something particularly well designed. I myself am not a fan of COM, and can hardly recommend it.Premundane
W
0

You might check into embedding Guile (a scheme interpreter) or V8 (Google's javascript interpreter - used in Chrome - which is written in C++).

Wisp answered 30/6, 2010 at 14:57 Comment(2)
Again, not looking for embeeding. Using V8 or Guile forces me to write ad-hoc wrappers for C++. I want the scripting language to be able to generate the .h and such.Bulganin
My fault for not reading your question carefully. I don't know of any language tools out there that would readily do what you want.Wisp
N
0

Try the Ring programming language 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

(2) Embedding Ring Interpreter in C/C++ Programs 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

Nephoscope answered 22/3, 2016 at 7:25 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.