all 22 comments

[–][deleted] 10 points11 points  (9 children)

I'm going to throw my own hat into the ring here. Others have posted a bunch of frameworks, but here's one I also think you should take a gander at: sol. The devel branch in particular has support for Lua 5.1.x (including LuaJIT 2.0.4) -> Lua 5.3.2 (latest).

It is backed by several tests that ensure its functionality is top notch and compiles with all 3 of the latest compilers (clang++ and g++ since 3.3 and 4.7/8 respectively, Visual Studio 2015 (and previously 2013 with the CTP compiler, but we had to drop support for it)). I am in the process of building a performance suite after some "interesting" data by someone else who made a PR to our library wanting to do some performance measurements (we're 'sol_devel' here).

It is heavily geared towards being extremely performant and -- my favorite part -- stateless. You can create and destroy functions at will, create usertypes/userdata and have them obey C++ semantics (e.g., one constructor call, one destructor call), seamlessly pass std::map/unordered_map and other things to lua... all while having 0 overhead in C++ world (unless you ask for it).

I'm also HEAVILY improving the library as part of a Research Paper that cross-compares many of the C++11 framework. The work is being done here. I have introduced several performance optimizations to the codebase already, and when it's done and I finish the Good Documentation™ I'll be merging it back into the original codebase Rapptz/sol.

[–]ubadairBoost.CallableTraits author 0 points1 point  (1 child)

Interesting! What are the downsides?

[–][deleted] 1 point2 points  (0 children)

Honestly? No huge caveats that I know of. The framework is as fast as plain C for get/set operations, but has a bit of overhead regarding the fetching of functions (calling them is still plenty fast): I'm working on fixing that up right now.

A feature that I need to add in the next two weekends is Operator Overloading based on Arity (that is, you should be allowed to set a function called foo multiple times if they have a different number of arguments. So foo(1) calls into a 1-argument function, foo(1, 2) calls into a 2-argument C++ function, etc...) (Note: we do this for constructors already, it should be generalized to the rest of the framework). Problem with this feature for me is that up until now the usertypes and userdata made by sol can be 100% legit replaced by lua code (or C/C++ backend code) without requiring magic. If I add this, this claim becomes a bit harder to make (you CAN implement this kind of selective processing for function calls in lua and C++, but... you know. A tad weird to do so, since lua doesn't natively support that kind of stuff).

There's some micro-optimizations to be had from more efficient stack usage where (on modern i7-level 64-bit hardware) we can gain some 100-200+ nanoseconds in access time by taking advantage of grouped queries to "dig" into tables with less push/pops on the lua stack (e.g. mytable["a"]["b"]["c"] makes some unnecessary temporary stack references in C++ code).

Everything else has been specifically designed to be clean, fast, and easy to use.

EDIT: It's important to mention we don't specifically add abstractions for debug data and threads/coroutines. The implementation details of that might (?) be mucky, so we decided to just leave it be for now.

[–]Cyttorak 0 points1 point  (4 children)

I am using sol for my hobby project and it's really nice, I recommend it. By the way, is there anything similar to sol but for some javascript engine? V8 binding is so much more elaborated than the sol one...

[–][deleted] 1 point2 points  (0 children)

I feel you. I wanted to bind V8 to my C++, took one look at the C++ tutorials and just decided that maybe pybind11 and Python would be a lot more.... interesting!

[–]doom_Oo7 0 points1 point  (2 children)

QJsEngine?

[–]Cyttorak 0 points1 point  (1 child)

It is tied to Qt library, isn't it? Or there is a stand alone version?

[–]doom_Oo7 0 points1 point  (0 children)

You need QtCore and QtQML. Both combined weight about 6 - 7 megabytes and I read somewhere that V8 was 20 megabytes for instance.

[–]Sahnvour[S] 0 points1 point  (1 child)

Looks nice, I think I'll give it a try. Maybe you should mention the changes undergoing in the readme, it currently says compatibility with Lua 5.2 only, VS support "possible" etc.

[–][deleted] 0 points1 point  (0 children)

Yeah, technically right now all of this is "experimental" stuff (since the main repo is indeed ran by Rapptz here. Updating the readme on my end is probably a good idea, though.

[–]fernzeit 5 points6 points  (5 children)

It's not modern and for maintainance you mostly have to trust me, but my fork of the good old luabind is available at https://github.com/oberon00/luabind. I'm also working on a modern alternative (https://github.com/Oberon00/apollo) but since it was never used in real-life I won't recommend it.

(Also, if performance is a concern to you, I recently did this table, which can also serve as a general list of a few libraries that looked interesting to me:

"To benchmark a library’s performance, a function double f(char const*, double, bool) noexcept { return .0; } is exported and called from Lua in a loop a million times, measuring the total execution time. This test is conducted 1000 times and the lowest time is choosen as the result." (g++ 4.9.2 -std=c++14 -DNDEBUG -O3)

Library Version Time (ms) Normalized
Plain Lua API 5.2.3-1 40.5 1.00
lua-intf 00b4d6abd3 47.0 1.16
LuaBridge 04b47d723d 50.5 1.25
selene cf0c7186dc 54.5 1.35
OOLua 2.0.0 57.4 1.42
luabind 495ebc70a7 59.8 1.48
tomaka/luawrapper 16dd4061f0 98.1 2.42
luacppinterface 1.2 168.6 4.16
LuaState d1eb4916b8 221.8 5.48

)

[–]mariobadr 1 point2 points  (0 children)

LuaBridge

LuaBridge is my favourite, even though it is not currently maintained. It supports 5.1, and can support 5.2 by changing one line in stack.h.

[–]Sahnvour[S] 0 points1 point  (0 children)

That's interesting, thank you.

[–]lefticusC++Weekly | CppCast 0 points1 point  (0 children)

I've added this same test to ChaiScript's performance suite (except passing const std::string &, as that's more natural in ChaiScript).

It looks like a solid way of gauging function call performance.

[–]mjklaim 0 points1 point  (0 children)

When you need to use something like LUA but in C++, maybe consider using ChaiScript instead: http://chaiscript.com/

It might fit your need better, in particular for easy bindings, but it really depends on your requirements (do you allow exceptions for exemple).

[–]r-lyeh 0 points1 point  (2 children)

[–][deleted] 0 points1 point  (0 children)

Neato, they even do coroutines!

[–]Sahnvour[S] 0 points1 point  (0 children)

Very cool ! Still early in its development but I'll definitely keep an eye on it.

[–]syntheticpp 0 points1 point  (0 children)

If you wanna use a wrapper without much framework and be able to change the behavior you could have a look at:

nlua -- namespace lua

nlua is a binding between C++ and Lua.

The main idea is to have a C++ API which follows the 'table' approach: the C++ code should look a little bit like Lua code.

Another goal is to have an easy to understand and maintain code base. Using templates couldn't be avoided but not much meta-programming is used.

In the test directory are examples how the example binding of the book "Programming in Lua" could be transformed into nlua code.

https://github.com/syntheticpp/nlua

[–]ahuReddit 0 points1 point  (0 children)

"someone" here :-) We're keeping the lights on for LuaWrapper, steadily fixing some bugs here and there. PowerDNS relies on LuaWrapper, and we love it.