Lua Turn C Struct Into Table
|
Lua doesn't have structs, it has tables. Userdata is a convenient way to pass opaque data to Lua, but Lua won't be able to see inside. Userdata is only useful if you pass it back to C and you have a way to determine what it is (essentially casting it to the right type). Lua tables are the closest to a struct in C. You can write something.
Contrary to the most popular languages today, Lua array indices represent an ordinal position within the array rather than an offset from the head of the array. (This scheme was unfortunately referred to as 'counting from one', leading many to defend it as the natural way to count. Really, the argument is in the use of offsets vs. ordinals to indicate an element within a sequence.)
There is exactly ONE spot in the core of Lua where this is true: the parsing of constructors such as {10,20,30}
. The convention of starting with 1 is only enforced by the libraries, which are not part of the language. --lhf
- This is no longer true with Lua 5.1, as the # operator is also dependent on a base index of 1.
From the Lua manual:
- The length of a table t is defined to be any integer index n such that t[n] is not nil and t[n+1] is nil;
- That definition (from Lua 5.1 manual) implies that the table { [-3] = 0 } has length -3, while a completely empty table {} has no length at all (rather than length 0). Which is more counter-intuitive than counting from zero is. For some reason, PUC-Lua 5.1 doesn't honour this definition: #{ [-3] 0 } 0. (Lua 5.2 manual changes the definition to one which explicitly counts from 1. Which is still rather ill-specified for an empty table, unless you know what the range {1..n} is supposed to be for n less than 1 -- and defining that without falling into a similar trap is somewhat tricky.) --f.
And aww, let's get over with this: Define a proxy table to the real table with the index metamethod overriden to access i-1 on the real table if i is positive. Decide whenever you'll map negative indices directly to the real table or if you'll further process them. Decide what you'll do with the index 0 on the real table.
That done, use the proxy table whenever you need to count from zero. Use the real table whenever you need library functions. For mnemonics, name your table 'tablename1' and the proxy 'tablename0'. Problem solved.
If you are a person referred to as a 'scripter' or 'non-programmer', here is a call to take a stand regarding future languages. Make it known that you are as perfectly capable of grasping the concept of offsets as any programmer. Lua lists have a base index of 1 because it was thought to be most friendly for non-programmers, as it makes indices correspond to ordinal element positions. However, this dubious concession causes programmers a lot of grief, which in turn decreases their efficiency in providing you with the tools to do your work. One reason is that Lua is tightly coupled with C which uses a base index of 0 for arrays-- the indices represent an offset from the head of the array. This means that programmers working on both Lua and C sides must constantly switch reference in both their code and mind, which is annoying and error prone. Also it turns out that using offsets goes hand in hand with a certain way of specifying ranges where the end is not included (known as a half-open range), while using ordinal positions does not. Half-open ranges allow more natural handling of zero-length ranges which leads to more concise and consistent programs.being both a C++ and a Lua programmer, i have to completely disagree with this rant. Counting from 1 is the 'natural' way of counting. In math, everyone counts from 1, too. Counting from 0 is only good for the C convention that an array and a pointer are equivalent, and that a[i] is the same as *(a+i). Also, i think, it is easy for a programmer to adapt to the non-C-like way of counting. Yet it makes Lua much more intuitive for 'casual programmers'. --PeterPrade
- Agreed, it is a rant :-). However, your argument doesn't address the issue of how half-open ranges allow more concise coding, which is my main point. When dealing with ranges Lua, programs will tend to be littered with
+1
's because Lua does not use half-open ranges, where as in C++ (especially when using STL, which uses that style of ranges in its entirety) this won't happen. In addition, I agree that counting from one is natural to humans (I never stated otherwise), however representing zero-length ranges with[n, n-1]
is very awkward. It is not natural to communicate 'take no steps forward' by indicating to someone a start point on the floor, and then a destination point one step behind. In contrast humans can easily understand 'take no steps forward' by indicating a start point on the floor, and a destination being that same point-- corresponding with the half-open range[n, n)
. --JohnBelmonte
- Set theorists, logicians and combinatoricists count from zero. The elements of Z/nZ (integers modulo n) rings are usually named {0, 1, ..., n-1}, so algebraists count from zero too. These are all disciplines quite intimately connected to CS and therefore programming. In analysis one often counts from 1, but it's not really relevant -- the set of natural numbers is usually used there for its topology, or simply as a convenient indexing set with well-defined 'move backwards' and 'move forwards' operations (and even then the definition is more elegant if you include zero), making the choice of a starting point rather arbitrary (it might have been 42 just as well). The choice of 1 is usually either out of habit, to avoid breaking 'backwards compatibility' (i.e. mutual intelligibility with material using one-based numbering), or to avoid considering a zero in a denominator/exponent/whatever. --f
Sometimes half-open ranges allow concise coding and sometimes not. I've seen (and committed) plenty of fencepost errors with both half-open and closed ranges. The fact that the last element in a C array has the index one less than the length of the array, for example, can lead to a variety of -1
's in code; it is certain that there are techniques for eliminating these, but I wouldn't say that my Lua code is any more littered with +1
's than my C code is with -1
's. With respect to half-open ranges, though, there is a serious problem: you need to be able to represent a quantity that is not in the range. Consequently, for example, the type of an index of a string of length 256 needs to be at least short, even though every valid index is a byte. Similarly, a half-open range descriptor to the end of a vector contains an address which is not included in the storage of the vector, and which may well a valid pointer to a different object; this gets complicated for conservative garbage collecting, for example. (At least one conservative garbage collector deliberately overallocates to compensate for this problem.) I'm not standing up for one or the other: both are valid, both have advantages, and both have disadvantages. --RiciLake
- Your argument doesn't hold water, RiciLake. You have an array of 256 bytes and you use a 'closed' representation, in which (n, m) means [n, n+1, n+2 ... m-1, m], to represent intervals in that array. The representation of a zero-length range then is (n, n-1) as noted above; for example, [4, 3]. So what's the representation of a zero-length range starting at zero? (0, 256) has another meaning. So your argument about how many bits you need for array indexes is equally a problem for half-open and closed representations of intervals. It's also irrelevant to languages like Lua in which you don't get to pick how many bits to use. --KragenJavierSitaker?
as with counting from one, i think closed ranges are much more intuitive than half-open ranges, at least when you're not talking about the special case of a zero length range. When i say 'intuitive' i mean it is more natural for someone who has not been a programmer at least for some years. --PeterPrade
I have not counted them, but I think that a vast amount of programming languages start counting at zero... And as I have learned C as my first language, starting at one seems confusing to --in fact I wrote a bunch of bad Lua code with arrays starting at zero in mind --AdrianPerez
Although counting from zero has its advantages, I find counting from one much more natural, even when programming. It is not a problem for me to switch between Lua and C, as in the past I've switched a lot between Visual Basic and C --Anonymous
First is 1st, not 0th --Kazimir Majorinc
'I'm in the process of evaluating Lua for an embedded scripting language in my app., and everything I have seen up to this has been very positive, until I realized Lua is counting things from index 1. Bad. Bad. Baaad. Bad enough to consider tossing the whole thing out the door. As for justification, even though there shouldn't be a need of any :),: indices of an array of length N are a natural map to the ring of integers modulo N, that have a lot of nifty properties. For example, when you want to access your array cyclically, you just do index = (index+1) %N
. Doing the same thing with indices starting at 1 is a pain the neck. Also, it makes binding C routines to Lua utterly painful.'
- index = index % N + 1 --Milano Carvalho
- Exactly, all of a sudden we have a bug and extra work where none needed to be. In addition, the programmer now has to remember 'Is index a position and violates modulo preconditions or is it the actual modulo?' Finally, what's the inverse of that? Is it: 'modindex = index - 1 % N' or is it 'modindex = index % N - 1'? Trick question: it's 'modindex = (index - 1) % N'. --Andrew Lentvorski
- agreed. the Lua C library interface to C uses conventions which are unnatural to C. for example when parsing Lua tables into C arrays you have to remember to use
iterator+1
to access the table index. --DanHollis?
- Lua 5.1 provides the
lua_createtable()
API call which allows you to specify the array size of the table (precisely). You can also specify the hash size, but that part is always restricted to a power of 2. If you create a table with a specified array size, its array part will be precisely that size so long as you do not force the table to expand, so it will work fine if you know the size of the table in advance. Binding arrays of small atomic objects, likeint
s, is made slightly easier in 5.1 as well, because of the possibility of overriding the#
operator, but to make theuserdata
really act like a Lua table, you need to modify the default definition ofipairs
and possibly ofunpack
. I've put some code for the former on the Wiki at GeneralizedPairsAndIpairs, in case it is of use to anyone. --RiciLake
- An excellent point, something I've struggled with too. Interfacing large C structs to lua, especially C arrays of large structs is not fun. Lua does not make these mappings straightforward. --DanHollis?
lua_Number
set to double as default. In the same way, it might be interesting to define a constant lua_FirstIndex
(for instance) set to 1 as default, to refer to the first index. Every part of Lua related with the first index of an array (for instance, ipair
, foreachi
, etc.) should use this constant. If a user wants to change this constant to 0 and recompile, he/she could use Lua tables beginning from 0 at his/her own risk of loosing compatibility. The same constant should be accessible from Lua to allow also scripts being portable or independent of the first value of index arrays. --Salvador Espana The question whether counting in computer science should be zero- or one-based is a classic one. I found the arguments in Edsger Dijkstra's article 'Why numbering should start at zero' (http://www.cs.utexas.edu/users/EWD/ewd08xx/EWD831.PDF) very convincing and I became a strong counting-starts-at-0 advocate. Too sad, Lua, suggests starting at 1. This will make table/array constructions awkward: {[0]=10, 20, 30}
and the table-library functions of lesser value. --Ulrich Hoffmann <uho@xlerb.de> - Yes, nice article. I especially like the very first sentence: 'To denote the subsequence of natural numbers 2, 3, ..., 12 [...].' Now, combine that with the metric that computer languages should primarily communicate their intent to the reader, and only incidentally to the computer, and we see that even for Dijkstra the most natural notation is the inclusive one... Draw your own conclusion.
[n,n)
but also adjacent ranges nicely add up -- [a,b)+[b,c)=[a,c)
-- without excessive doubling at the ends. The resulting range is (b-a)+(c-b)=c-a
-long, and any or both of the components can be zero-length. Also, one can consider `negative ranges' [m,n)
where m>n
and the addition of ranges still works, now being even possible to obtain a zero-length range from non-zero ones. Now, consider numbers a
, b
, and x
. A correct expression for `x
is between a
and b
' in the sense that min(a,b)<=x<max(a,b)
(a half-open range) is (a<=x)=(x<b)
. Were it a closed range (...<=x<=...
), we wouldn't have had such a nice expression. -- Boyko Bantchev
As a script language its first priority is to be easy for scripters to use. An array of 5 elements that has the last element as number 5 is surely easier to explain to casual scripters, than that it finishes at element 4?
I have interfaced many client functions in my system to expose their workings to Lua. The question of zero-or-one based doesn't even apply in many cases. For instance, a lot use string keys (in which case the problem goes away), or they don't use an array of any sort.
If you want Lua to be a universal scripting language I certainly would not recommend a compile-time option, so that half the Lua scripts published work based on zero and half based on 1. You would be opening the doors to a nightmare doing that. I can't even see how that can work if you want to interface things like LuaSocket
, LuaCom
etc. These would be written assuming the current convention, that arrays start at 1, and many are supplied with precompiled binaries for Windows. These would either not work at all if you ran on a zero-based system, or the authors of each package would have to clutter their code with tests for what the base is, surely losing any advantage of changing it in the first place. -- NickGammon
Thus, programmers who are interfacing Lua with C are very familiar with that convention - you have to be. Again, if you made arrays zero-based, would you change that too? In which case how do you get the last element from the stack (which is currently -1)?
Some of the posts above don't really mention if they are referring to strings as well. For instance, the first item in a string:
Would you make that zero also? If so, how do you get the last item? -- NickGammon
Using -1 as an alias for the last element is perfectly consistent with half-open ranges (i.e. counting from zero). See Python. In fact, it is more consistent than with closed ranges. Consider for a moment that lists wrap around, and you can move from beginning to end and back the 'short way'. One left of position 0 (the beginning of the list) is -1 (the end of the list). In other words you can just subtract 1 from your position to move left, which is natural. If you start a list at 1 instead, it produces a strange gap of two positions between the beginning and end. To move to the left, you'd have to subtract one from your position, unless you were at position 1, in which case you'd subtract 2.
- Then do you also propose that greatest_index + 1 wrap around to the first element? If not, there would still be these 'strange' jumps when going from the last element (specified with positive index) to the first, so that argument doesn't make any sense.
- No-- if you want indexing to wrap, use i modulo n. The simplicity of that equation is one of the attractive points of indexing with offsets.
Yes, that is true. However given that the 'deed is done' now, I suggest that applications that need the 'count from zero' approach for mathematical or other reasons, simply define their own foreachi
function to work around the current behaviour. After all, there is nothing stopping you from putting elements into position 0 of a table right now.
If you want to make a table constructor start at 0 do this:
-- NickGammon
Unfortunately #t evaluates to 2. Much of the problem arises from the confusion of numerals with ordinals. When indices are offsets, 0 is the offset of the first item in the array. If we were a bit more scrupulous in retaining the type information with the use of numbers in vernacular speech there would be less contention on this. In mathematics, realizing a non-negative integer n as the set of numbers from 0 to n-1 inclusive gives much neater formulae than identifying it with the set of numbers from 1 to n. -- GavinWraith
- Though in math, it is common for matrices and vectors to be 1-indexed[1][2][3]. Similarly, in LuaMatrix, the first element is referenced as
mtx[1][1]
. Sequences maybe vary more[4]. Concerning math software, Mathcad by default 0-indexes (though it can be changed), while Matlab, Maple, and Mathematica 1-index. --DavidManura
#t
(or, table.getn
) is not defined as returning the number of elements in a table. For example: From the Lua manual:
- The length of a table t is defined to be any integer index n such that t[n] is not nil and t[n+1] is nil;
My example is consistent with the definition. #t
returns the index of the last item.
-- NickGammon
- It isn't. t[0] is nil. According to that definition, this table has no well-defined length at all. See above. --f
- An array subscript n, where n is any non-negative integer, always refers to array element n+1.
It is obvious we are not going to reach agreement here, however don't you think that is just slightly confusing? 'Subscript n ... refers to element n+1?'. At least in Lua, subscript n refers to element n.
-- NickGammon
- It's only confusing if your base is 0 and you think of the index an a position. If your base is 0 then the index is best thought of as an offset from the start of the list, not a position. This is the same point just made by Gavin. Generally speaking, offsets are more useful in programming than positions.
IMHO counting from 1 is great. First element is 1, last element is -1. No need to remember 'this is not math, this is not something natural, get used to it', like when you deal with indices in python.
-- muntyan
And Lua lets you store 0 in your integers -- so which element does it get you?
Lua's key advantage is that it is the most embeddable of the scripting languages -- it really isn't the best top-level scripting language for general programming tasks (python and perl are better). As an embedded scripting language, it is going to be embedded in compiled languages. Almost all of them use 0-based indexing, so most of the new users are going to have this frame of reference. VB had this debate (and the dyanmic option to choose), and from what I've seen, people voted for 0-based indices. So let's just do this and get it over with. -- GRBE x a c t l y -- JeanClaudeWippler
- Please don't write in the first person without signing your name.
It looks like counting from one is a very old legacy from unary systems. We should have get rid of this when inventing the zero but unfortunately we did not.
Counting from 1 is the number one reason why I don't use Lua. Other than this, it is a very nice language, but it is just so much easier to code with half-open ranges. I disagree when people tell me 'it is more natural to count from one.' It is just an old leftover from the past. If you really think about it, it makes a lot more sense to count from 0.--Zifre
- Zifre, don't you mean, 'Counting from 1 is the number *zero* reason why I don't use Lua.'? After all, you claim that counting from zero makes so much more sense to you.
Let's make a bet. We will go to a park and talk to random people. We will show them three stones in a line, and ask them to count the stones aloud. If any person says, 'Zero, one, two', then you win. If everyone says, 'One, two, three', then I win. I imagine that I would always win this bet. No one counts from zero, because it makes no sense. When the first element of an array is accessed with 0, then that number represents an offset, not an index. The question is not about counting, it's about whether arrays should use offsets or indices.
Using offsets rather than indices does have some advantages, of course. But it's hard to argue with this: If arrays use indices, then the 'nth' element is accessed with the number 'n'. Do you want the fourth element? Then use 4. Want the tenth? Then use 10. That makes a lot of sense, and has its own set of nice properties. Unfortunately, many programmers are closed-minded on this issue, and somehow convince themselves of absurd statements like, 'It makes a lot more sense to count from 0.' (And then, in their own post, illustrate that they in fact count from one, just like everyone else on this planet.)
Let's make a second bet. After asking people to count the stones, we will say, 'Please point to stone one'. If anyone points to the middle stone, then you win the bet. Otherwise, I win. Again, I don't see how I would realistically ever lose this bet. -- Anonymous
- Zifre vs. anonymous adds nothing to the discussion on this page. Did you read the first paragraph? The issue is not about counting from one or zero, but rather how to indicate an element within a sequence. Using offsets results in less edge cases and hence simpler code and API's. This has nothing to do with how people in a park count. --JohnBelmonte
- Considering one of the major current uses for Lua is amateur scripting, e.g. in places where you're allowed to not be a skilled programmer but are still presented with the gift of customization, how 'people in a park' count is fairly relevant. Not that everything should be dumbed down for the purpose of the almighty consumer, especially the tools with which a programmer is supposed to conduct their business, but since the debate of offset vs. cardinal is largely a conceptual problem, relating to how you internalize what your code is supposed to mean, why fault Lua for pandering to the person in the park, where the first stone in the stone array is stone 1? Offsets, to those who are unfamiliar with them, are a bit of a barrier to entry.
- Well, put a computer to count those 3 stones. You will get something along this lines: 00, 01, 10. You are missing the big picture here: you don't program people, you program computers. Knowing the computer's internals usually helps. You can't ever make a computer to totally understand you (or maybe you can, but in that case you should get a Nobel prize). However, you can totally understand a computer :) -- shiretu
Also, the statement that this: [a,b]+[b,c] should have been this: [a,b]+[b+1,c] is completely off, as the original proposition needed half-open intervals, in which case, it looks like this: [a,b)+[b,c)
Therefore, the complaint is completely off, as [a,b)+[b,c) does NOT include b twice. I am going to correct that part and delete the rant about [a,b]+[b+1,c], because it's pointless. --Tim
JohnBelmonte, using offsets doesn't results in simpler code APIs. Agree, fewer edge cases, but don't try to convince people to like/dislike a particular programming pattern. What is important here is that Lua should support diversity. I myself have hard time designing 1-based code and is way more prone to errors than yours so called 'edge-cases'. In another words, I instinctively know how to avoid edge cases using my skills developed with the rest of 10001 programing languages rather than adoption your 'safe' method of developing 'simpler code'. Really, is just a matter of taste. You can't categorize people in 'you are stupid because you code this way, you are smart because you code that way'. Despite the fact that I hate this about Lua, it still gets a lot of love from me because so many other positive facets. I do miss one tho... Being able to specify the index base at compile time... --shiretu It's wrong. Here's why: Edsger Dijkstra's note on starting array indices at 0 (pdf, 1982) [5]. -- Anonymous I've made an attempt to patch on Lua 5.3.4 source distribution, including ALL official libraries: lua-base-0. Open-sourced[6]. If you are interested, please go to check (and port to the latest lua, write some test cases for the best) if I missed something.Some exceptions:
- In
string.gmatch
,'%0'
is for the whole match, and'%1%2'...
for the first, second captures. Unchanged.
- The definition of subscription of
args
table is unchanged, but note that the length operator will now return a number larger by 1.
math.random
is an uncertain point. The current status is most for practicability: it returns [0, n) when 1 argument is provided, [a, b] for 2.
- Numeric for loop is another. The current status is: {0,1,2} for
for i=0,3
and {3,2,1} forfor i=3,0,-1
.
- I'm considering to make the latter {2,1,0} too, since it just works as backward iteration. But it'll just look ugly on definition, also some problem floating-point numbers may occur. (But I wonder, honestly, who have ever used it in production? ) What do you think?
- The border case of table.remove where
i#t+1
(i#t
base-0) is removed. I don't understand it. It raises an error now.
The rest should be trivial, including some circumstances where negative indices are supported as reversed, where it'll work mostly like in python.
Another point for my contrary to base-1 table: It causes problem and confusion when converting from/to JSON, which is a widely used data exchanging format.
--farter
See Also
RecentChanges · preferencesedit · history
Last edited March 19, 2018 1:54 am GMT (diff)
|
Lua can be embedded and extended[1] with code or applications written in other languages. Code and values in another language can be exposed to Lua and vice-versa. The following lists low and high level solutions for binding between Lua and other languages.
Lua C API
The most direct method to bind to Lua is with the Lua C API. The C API consists of two parts: the basic API (lua.h) provides the primitive functions for all interactions between C and Lua, while the auxiliary library (lauxlib.h) provides higher-level functions for some common tasks.[2]
- [The Lua 5.1 Reference Manual: The Application Program Interface] (5.1) describes Lua's native C API for calling Lua from C and vice-versa.
- See also Lua book [PIL2]. Or read about the C API online in the 1st edition of PIL: [PIL1 - The C API]
- An introductory video on embedding Lua in C++: [Embedding Lua in C++ #1]
- A tutorial for embedding Lua in C: [Embedding Lua in C]
Enabling API checking
By default, the Lua C API does almost no sanity checking of arguments passed to it. Passing incorrect stack indexes, for example, can result in segfaults or random data corruption. You should always enable API checking in any debug build. You can do this by compiling with the option -DLUA_USE_APICHECK
. luaconf.h
uses this C macro to define luai_apicheck
to call assert()
in various places (you can also edit this definition to do something possibly more useful).
Example
Some examples of using the C API can be found by examining the source code of Lua's own standard libraries (src/*lib.c
}. For example, the math library (math.*
) is implemented in the file src/lmathlib.c
. The basic form of this file is outlined below. First we import various headers, including the C API (lua.h) and the auxiliary library (lauxlib.h):
Lua Turn C Struct Into Table Saw
Then various Lua functions implemented in C are defined. These all have the same signature, and arguments are passed via Lua's own stack. For example, the sin function is defined as follows. luaL_check_number()
is used to check the correct type of the sin
function argument. lua_pushnumber()
is used to return the sine calculated. Note, the return value of the math_sin()
function is the number of values returned (lua functions can return many values).
These functions are registered into Lua by building a table of function pointers and names and then calling luaL_register()
. Constants pi
and huge
are set separately. This registration code is placed in a function named luaopen_math()
, which can be called statically (e.g. from linit.c) or dynamically (via Lua's shared library loading mechanism via require
).
Binding C/C++ with Lua
C
- [LuaAutoC] (5.2) - Automatically wrap C functions and structs at runtime.
- [LuaNativeObjects] (5.1) - A C bindings generator written in Lua. It turns C structs into objects.
- [luapi] (5.0) - a C API over the official Lua API.
- [CaLua] (5.0) - A way to bind C functions and structures to Lua, and work with C pointers, arrays and functions in Lua. (uses x86 assembly)
C Foreign Function Interfaces (FFI)
- [Alien] (5.1) - a foreign function interface (FFI) for Lua. An [FFI] lets Lua code call C functions directly without having to write C 'glue', so you can use Alien to write C extensions purely in Lua. (Wraps libffi)
- [C/Invoke for Lua] (5.1) - Use [C/Invoke] from Lua to call C libraries (DLLs, .so files) directly, like Microsoft's P/Invoke and Python's ctypes. (Similar to Alien)
- [The LuaJIT FFI] allows calling external C functions and using C data structures from Lua code. It parses plain C declarations and supports C99 plus some GCC/MSVC/C++ extensions.
- [luaffi] (5.1) - an implementation of LuaJIT FFI for Lua.
- [cffi-lua] (5.1, LuaJIT, 5.2, 5.3, 5.4) - Mostly compatible with the LuaJIT FFI (but integrates with new Lua versions), but portable (libffi based) and implemented from scratch.
C Inline
- [lua-tcc] (5.1) - Simple interface to TCC, a fast runtime C compiler by Fabrice Bellard, it allows a Lua script to compile C code and register it at runtime as Lua-callable C funcions. Intentionally limited to avoid TCC's bug with multi-environments, that would be too tempting in Lua.
- [Luatcc] (5.1) - another, more complete, Lua binding for libtcc, which is the core library of the [Tiny C Compiler]. It allows compiling and loading C code directly from Lua, includes the ability to load C modules directly from C source.
- InlineCee provides a similar approach, invoking other compilers out-of-process.
C++
Various C++ or C++ template bindings have been developed to simplify the process in C++:
- [MiniLua (5.3, 5.4)] - Minimal Lua interface for loading a lua-file and getting values into your C++-application.
- [Lua-Adapter] (5.3, 5.4) - Use this lightweight wrapper-/adapter-class as a simple 'interface' between Lua and C++.
- [CppLua] (5.0 & 5.1) - a C++ wrapper of the Lua API; handles class member functions.
- [LuaCppInterface] (5.2) - a C++ wrapper of the Lua API. Uses TMP to make calling/passing functions, handling coroutines and filling tables easy and type-safe.
- [sol2] (5.1, LuaJIT, 5.2 & 5.3) - a fast, powerful and easy C++14 wrapper for the API including support for table indexing, user-defined types, metamethods, coroutines and more.
- [sol] (5.2) - a C++11 easy to use and type safe wrapper of the Lua API.
- [Diluculum] (5.1) - A library that intends to make the coexistence of C++ and Lua more harmonious.
- [Tomaka17's lua wrapper] (5.2) - Simple bindings for Lua using C++11 supporting class and function registration, custom member functions, multiple return values, tables and more.
- [Luabind] (5.1 & [5.2]) - a template-based binding of C++ classes and functions which uses the Boost library. The library seems to be abandoned by the [original authors], but some more or less actively maintained [forks] exist, e.g. [3] or [4].
- [LuaBridge] (5.1 & 5.2) - lightweight, dependency-free, template-based library for exporting C++ classes/functions to Lua environments.
- [LuaBridge3] (5.1 & 5.2 & 5.3 & 5.4) - lightweight, dependency-free, template-based library for exporting C++ classes/functions to Lua environments, next generation with more feature and fixes.
- [SLB] (5.2) - Simple Lua Binder, a cross platform, small, easy to integrate, template-based library. Very similar to Luabind or boost-python but SLB doesn't require boost or any other dependency.
- [Luna] (4.0), LunaWrapper (5.1) and LunaFive (5.2) - clean, template-based method of binding a C++ class to Lua. See also [LTN5] and SimplerCppBinding.
- LunaWrap (5.2 & 5.3) - clean, template based way of pushing arbitrary types to and getting them from Lua, as well as a COMPILE-TIME 'proxy'-function ('int foo(lua_State*)') generator for C++ member functions!
- [MLuaBind] (5.1) - a template-based binding of C++ classes and functions which uses the Loki library.
- [MultiScript] (5.1) - a simple library that demonstrates Lua independent C++ interface to bind C++ classes and functions.
- [OOLua] (5.1, 5.2 & 5.3) - Cross platform template generator binding which has no dependencies.
- [Selene] (5.1, 5.2, 5.3) - Dead simple and intuitive C++11 bindings supporting class registration and functions.
- [Sweet Lua] (5.1) - a template-based binding of C++ classes and functions. (MSVC)
- [lux] - emits functions at compile time via C++ templates and argument overloading
- [nlua] - 'namespace lua' binding of C/C++ functions, table-like usage, templated based (no boost)
- [LuaWrapper] - A single header library that provides type-safe and intuitive functions such as luaW_to<T> and luaW_push<T> for arbitrary types, to make managing C++ classes with Lua simple.
- [Lutok] - Lightweight C++ API for Lua. Lutok provides provides thin C++ wrappers around the Lua C API to ease the interaction between C++ and Lua. These wrappers make intensive use of RAII to prevent resource leakage, expose C++-friendly data types, report errors by means of exceptions and ensure that the Lua stack is always left untouched in the face of errors. The library also provides a small subset of miscellaneous utility functions built on top of the wrappers.
- [integral] (5.1, LuaJIT, 5.2, 5.3, 5.4) - C++ library with no dependencies for creating Lua bindings.
- [lua-intf] (5.1, 5.2 & 5.3) - Pure C++11 API and binding for Lua (headers only), supports lua stack API, a higher level API that can refer lua object just like a C++ class object, and can also export C++ class and functions for lua script. The export binding supports custom C++ type, multiple return values, C++ shared pointer, in/out arguments, and can also make argument optional or with default value. The new version also comes with an optional Qt data type mapping (QString, QVariant, QByteArray, etc...).
- [LuaState] (5.1 & 5.2) - C++11 template library (clang, gcc and VS 12) no boost. Made to be really easy to use and as fast as possible. Lambda based bindings from Lua to C++.
- [Kaguya] (5.1 , 5.2 , 5.3) - C++03 with boost or C++11 template library.
- [Lua-Primer] (5.2, 5.3, Eris) - C++11 template library. Not only creates bindings to lua, but does it in a way that supports easy, seamless serialization using Lua Eris. See also [github] descriptions of eris.
- [Ponder] (5.3) Ponder is a C++ reflection API that can expose the API declared to Lua. Easy to use.
- [Automagical Bindings] Using C++11 templates to deduce C function arguments to automagically create wrappers to expose native C functions to lua code.
See also:
- DoItYourselfCppBinding - provides a few simple code fragments for helping Lua and C++ work together
- LuaGenPlusPlus - luagen++, a C++ header file to generate efficient sequences of Lua C API calls at compile-time via template metaprogramming techniques
- CppStreamChunkReader - lua_load chunk reader for any C++ std::istream (function)
- [A comparison of LuaBind, SWIG, OOLua, and toLua++] - One developer's attempt to find a good binding framework for use in a memory-constrained environment.
- [C++ Binding Benchmarks] - performance benchmarks for various C++:Lua bindings. [Github benchmark project here]
Calling Lua from C/C++
These frameworks and articles are one-way bindings: to call Lua functions from C/C++ passing arguments and getting return values.- [A Generic Call Function] (5.0) - from PiL uses a format string to call a global function with a variable number of arguments.
- [LuaGenericCall] (5.1) - uses code snippets and printf/scanf like format strings to support many types and features.
- [LuaClassBasedCall] (5.1) - uses code snippets along with C++ constructor overloads and templates, supports nearly all C++ types.
- [lua_icxx] (5.1) - embeds a Lua interpreter in a C++ application, using an OO API. See also SimpleLuaIcxxExample.
- SimpleLuaApiExample - example using the C API: the C program loads/runs a Lua script file, sets Lua variables and retrieves return value.
- CppLuaDataPassing - another more advanced example using regular C API to run a Lua script file with arguments.
- GettingValuesFromLua - explanation of how to get return values from
lua_dostring
. - CallingLuaFromCpp - example to use the
Luna
binding (see above) to call Lua from C++.
Embedding Lua in C++
These frameworks are a little broader than the previous ones: they allow your C++ program full interaction with a Lua interpreter, but leave the task of extending Lua to other binding systems (SWIG, tolua++, and others).
- [lua_icxx]: (pronounced 'lua-ix') Lua interpreter for C++; call Lua functions and User Data (class) methods, use tables, create function sandboxes, use multiple return values, evaluate expressions and scripts, and more. The missing link for use of bindings like SWIG and tolua++.
Automatic binding generators
- [toLua] (5.2) - If there is a lot of information to bind then automating the process using a binding generator can help. toLua is one such tool. A package file is prepared, which is a cleaned up version of the C/C++ interface. Another advantage of this technique is that less work may be required between Lua versions if the Lua C API changes significantly.
- [tolua++] (5.1) - an extended version of tolua, with some extra features oriented to c++. See also CompilingToluappWithoutScons (compiling tolua++ without SCons).
- [CPB] (5.0) - A simple, fast, and powerful binding library for the Lua scripting language. It takes the information from the compilers symbols and generates binding code directly from it. (MSVC)
- [SWIG] (5.0/5.1) - Simplified Wrapper and Interface Generator, it can generate bindings between your C/C++ code and a variety of scripting languages (Python, Perl, Tcl/Tk, Ruby, ...), including Lua. A big advantage might be that *one* interface file, similar to that used in tolua/tolua++, is used for bindings to all languages supported by SWIG. See also the SWIG docs pertaining to Lua [5].
- [luna-gen] - lua binding-code generator that supports features such as properties, inheritance (both from lua and c++), namespace, enum, type-checking, c++ exception handling, adopt-policy, g++ and MSVS, operator overloading, user-configurable custum string and number/enum types and so on. Fast compilation and execution speed (much faster than luabind and SWIG), human-readable output codes, no boost dependency.
- [dub] - Uses Doxygen to parse C++ headers. Supports features such as properties, inheritance, type casting, Lua wrapping, enum, exception handling, operators, custom type binding, C++ template resolution, C++ callbacks with error handling, overloaded methods with runtime type resolution, etc. The generated code is optimized to be as fast as possible (return value optimization, inline objects, etc).
- [Ponder] - After declaring an API using Ponder it can be automatically exposed to Lua. Ponder is a C++ reflection system that also supports Lua binding, and XML/JSON serialisation.
Proxy wrapper for DLL
Function information can be exported from dynamically linked libraries. [FuBi] describes a method to call these functions from script (or RPC). This functionality can be used from Lua [6].
Miscellaneous
- [wxScript] (5.0) - A set of abstract classes to add script-interpreter support to your wxWidgets applications/libraries.
Other languages
Ada
- [Lua-Ada] (5.0) - Lua binding to Ada 95. (link broken)
- [lua-ada] (5.1) - Ada bindings to the Lua language (public domain) (link broken)
- [AdaCore ada-lua] (5.2) - Ada bindings to the Lua Language with generic packages to ease binding of Ada types to Lua
Bash Shell
The luabash tool is a dynamically loadable module for the bash shell that provides a bridge between the bash shell and the lua scripting language. This enables complex embedded code segments to be replaced with efficient lua code and the speed of shell scripts to be increased without the drastic need to rewrite existing code.
Basic
- [FreeBASIC] - A open-source BASIC compiler that comes with the Lua headers and libraries.
- [PBLua] (5.0.2) - a Purebasic library wrapping Lua 5.0.2. (deprecated)
- [PowerBLua] (5.0) - PowerBASIC include & source for wrapping Lua (work in progress).
- [BlitzMax] (5.1.2) - a BlitzMax module wrapping Lua 5.1.2 (note: the link currently points into this wiki (which is usually a bad idea in this list) but this will change as soon as the package has its own web site)
COBOL
- [OpenCOBOL] (5.1) - Using Lua with OpenCOBOL 1.1
- [OCLua] - Generated documentation from the OpenCOBOL interface source code
D
- [LuaD] (5.1) - Lua bindings and high-level interfaces for the D programming language.
- [DLua] (5.1) - Lua bindings for the D programming language.
Erlang
- [erlua] (5.1) - aims to enable seamless interoperability between Erlang and Lua.
- [erl-lua] (5.1) - an Erlang linked-in driver that allows embedding Lua into the Erlang VM.
- [erluna] (5.1) - Lua bindings for Erlang.
Fortran
- [Aotus] (5.3) - aims to enable seamless usage of Lua scripts for configuration of Fortran applications, uses the ISO-C-Binding.
- [f2k3-lua] - Interaction with Lua via the Fortran 2003 ISO-C-Binding.
Go
- [golua] (5.1) - Lua bindings for Go.
- [luar] (5.1) - a reflection layer on top of golua API providing a simplified way to publish go functions to a Lua VM..
- [go-lua-test](5.1) - Examples using various Lua bindings for Go
Haskell
- [HsLua] (5.1) - Scripting.Lua binding for Haskell.
Java
- [LuaJava] (5.1) - allows scripts written in Lua to manipulate components developed in Java (JNI to native Lua) and vice-versa.
- [JNLua] (5.2, 5.1) - another Java JNI <-> Lua bridge. Includes JSR 223 (Scripting for the Java Platform) provider.
- [jna-lua] - Java JNA <-> native Lua bridge.
- [java-lua] - Java JNI Lua bridge. Calls Lua from Java as well as Java callbacks from Lua
LabVIEW
- [Lua for LabVIEW] (5.0, 5.1) - embedding Lua into National Instruments LabVIEW software.
Objective-C
- [LuaObjCBridge] (5.1) - calling Lua from Objective-C and vice-versa (MacOS X Cocoa).
- [LuaCore] (5.1) - a LuaObjCBridge-based framework, makes it easy to setup and run Lua scripts.
- [LuaCocoa] (5.1) - spiritual successor to LuaObjCBridge/LuaCore?, bridge between Lua & Obj-C, and uses Apple's BridgeSupport? to fill in remaining non-ObjC areas (e.g. structs, C functions, inline functions) to access all APIs on the platform. Also includes a command line tool suitable for writing AppleScript? in Lua via ScriptingBridge?. (Mac OS X).
- [iPhone Wax] (5.1) - a bridge between Lua and all the Objective-C/CocoaTouch classes.
- [Objective Lua] (5.1) - brings Objective-C-like syntax to Lua.
- [TLC] (LuaJIT 2) - A lightweight (Under 400 lines, pure Lua) bridge that exposes Objective-C objects&methods to Lua.
OCaml
- [ocaml-lua] (5.1.x) - calling Lua from OCaml and vice-versa (tested only in Linux, should work with OS X).
Pascal
- [VerySimple.Lua] (5.3) - Delphi XE5-XE7 Lua interface with OOP callback functions for Win32, Win64, Mac OS X, iOS and Android.
- [Freepascal bindings] (5.1 to 5.3.4) - Free Pascal bindings for the Lua library.
- [Pascal bindings] (5.1 to 5.3work1) - Pascal bindings for the Lua library, both for Delphi and Freepascal.
- [LuaPascal] (5.1) - Integrates Lua and Object Pascal languages. Allows Lua to manipulate components developed in Pascal/Delphi.
- [Lua4Delphi] (5.1) - Delphi and VCL Lua interface and Util functions.
- LuaDelphi (5.1) - calling Lua from Delphi/Pascal.
- [Lua4Delphi] (5.1) - for Delphi 2010 and XE.
- [THlua] (5.0) - Lua distribution for Delphi/Kylix/FreePascal. Includes header files, samples, some utils. For Windows, there are also LuaBinaries and project files for Visual Studio 6. Last updated in 2003.
- [Delphi-Lua] (5.0) - calling Lua from Delphi/Pascal.
- [DLua] (5.0) - calling Lua from Delphi/Pascal.
- [Free Pascal] Pascal units lua, lualib, lauxlib corresponding closely to the usual C API and axiliary library. See LuaInFreePascal.
Perl
- [LuaPerl] (5.1) - calling Perl (5.8 and 5.10 streams) from Lua.
- [Inline::Lua] (5.1) - calling Lua from Perl (inline).
- [Data::Lua] (5.1) - parse variables out of Lua code. Relies on Inline::Lua.
- [re::engine::Lua] (5.1) - supplies the Lua regular expression dialect for Perl.
PHP
- [LuaPhpExtension] (5.1) - PHP extension which allows embedding the Lua interpreter in a PHP application.
- [Nutria] (5.1) - PHP Standard Library written in Lua.
Python
- LunaticPython[7] (5.1) - Lua/Python two-way bridge. Allows embedding of Lua interpreter in Python programs, and embedding of Python interpreter in Lua programs.
- [Lupa] (LuaJIT2)(5.1, 5.2, ?5.3) - Embedded Lua in Python. Allows two-way communication between Python and Lua code and tries to adhere to common behaviour on both sides.
- ffilupa [8] (5.2, 5.3) - A modern two-way bridge between Python and Lua. Integrate Lua into Python using CFFI as backend, which runs fast on both CPython and PyPy?. Inspired by Lupa.
R
- RClient [9] (LuaJIT) - LuaJIT client for Rserve which is used to host a (local or remote) R session toward which a connection is established. A library that allows to execute arbitrary R programs within LuaJIT.
- Lupa (python packaged mentioned above) + reticulate (package for and installed from CRAN within R: https://rstudio.github.io/reticulate/) - workaround that allows one to access Lua language and objects while in R session by passing through python session as an intermediary set up by the Reticulate. Best to review examples in both LunaticPython and Lupa to understand how to set up and use this workaround.
Ruby
- [RubyLuaBridge] (5.1) - calling Lua from Ruby (calling Ruby from Lua is planned)
- [rub-lua5] (5.0) - calling Lua from Ruby.
Tcl
- [ltcltk] (5.1) - a binding of Tcl and Tk for Lua.
- [LuaTclBridge] (5.0) - a Lua<->Tcl bridge.
- [TcLux] (4.0) - Tcl extension which embeds Lua into Tcl.
- See also [Lua] on Tcl.tk wiki.
Terra
[Terra] is a new low-level system programming language that is designed to interoperate seamlessly with the Lua programming language.
Like C, Terra is a simple, statically-typed, compiled language with manual memory management. But unlike C, it is designed from the beginning to interoperate with Lua. Terra functions are first-class Lua values created using the terra keyword. When needed they are JIT-compiled to machine code.
You can use Terra and Lua as:
A scripting-language with high-performance extensions. While the performance of Lua and other dynamic languages is always getting better, a low-level of abstraction gives you predictable control of performance when you need it.
A JIT compiler for your software's DSLs. Meta-program Terra using Lua. allows you to compile domain-specific languages (DSLs) written in Lua into high-performance Terra code. Embedding Terra-Lua programs in other software as a library allows you to add a JIT-compiler into your existing software.
A stand-alone low-level language. Terra was designed so that it can run independently from Lua. In fact, if your final program doesn’t need Lua, you can save Terra code into a .o file or executable. In this use-case, Lua serves as a powerful meta-programming language. You can think of it as a replacement for C++ template metaprogramming with better syntax and nicer properties.
Frameworks
CORBA
- [OiL] (5.1) - ORB in Lua ([CORBA])
Windows COM
- LuaCom - (5.1/5.0) Lua interface to Microsoft's Component Object Model (COM). Calling COM objects from Lua and implementing COM objects in Lua.
Lua Turn C Struct Into Tableau
Windows .NET
- [dotLua] (5.0) - A .NET/CLI library, wrapping the Lua API.
- LuaInterface[10] (5.1) - a library for integration between the Lua language and Microsoft .NET platform's Common Language Runtime (CLR). Lua scripts can use it to instantiate CLR objects, access properties, call methods, and even handle events with Lua functions.
- [LuaNETInterface][11] (5.1) - a modification of LuaInterface to provide definition of Lua functions using attributes and loaded into the Lua engine using reflection.
- [NLua] (5.2) - a fork of LuaInterface which is active as of 2014
- [Eluant] (5.1) - a library with a similar purpose to LuaInterface/NLua, but fixing the memory management problems with LuaInterface/NLua. Active as of 2015.
- [LunaRoad] - Lua C API (v5.1, 5.2, 5.3, ...) for .NET / represents a flexible platform to work with Lua. Provides Lua interfaces, Lambda expressions, Dynamic features that can be used to generate new API-Layer automatically at runtime, etc. Active as of 2016.
Firefox
- [Moonshine] - embedded Lua environment for the Firefox web browser. Allows Firefox extensions to be developed in Lua rather than JavaScript. Implemented as an extension (XPI), written in XUL, JavaScript, and C++.
XML-RPC / SOAP
- See LuaXml.
See Also
- BindingEnumsToLua - a technique for synchronizing C enums with a Lua API
- EasyManualLibraryLoad - greatly simplifies manual loading (GetProcAddress? or dlsym) of Lua 5.1 shared library (.dll or .so)
- BoundScalarGlobalsOne/BoundScalarGlobalsTwo
edit · history
Last edited June 6, 2021 9:00 am GMT (diff)