How to pass an object from c++ to Lua and opposite? - c++

I have an object created in c++, I want to pass it to Lua, in Lua i need get that object and pass to c++.
in c++:
class Measure
{
public:
Measure();
private:
int value;
}
Void PassObjToLua(lua_State *L)
{
Measure * m=new Measure(); // I need to pass this object to Lua
// How to implement?
}
Void GetObjFromLua(lua_State *L)
{
//I need to get Measure object from Lua. How to implement?
}
In Lua script.
Local measure=nil;
measure= PassObjToLua();
GetObjFromLua(measure);
What do i need to do?

The best way I know of is the Sol library, which exposes a C++ interface.
Its userdata example shows how the library can be used to create tables linked to the C++ objects.
This answer might look like it's link-only, but you only really need to take a peek at how complicated the library is to realize that the question can't really be answered in one, simple answer. There are numerous caveats with regard to using the C API and wrapping it in C++ primitives.
I personally dislike the macro-based reflection-like binders and would recommend against using one, altough of course other people might have different opinions.

As Marcus wrote, you need to use the Lua C API in some way. To do it, you can either use a C code generator, or a Lua wrapper. You have examples of both on the lua wiki site, as well as instructions on how to write your own Lua wrapper.
EDIT: To expand my answer a bit. You need to represent a C++ class type instance as a lua type instance. The 2 options that are most popular are: representing a C++ object as a lua table or a lua userdata with a metatable attached. If you choose to use a lua table, you have the options of filling the table with keys, that are mapped to CFunctions, or use a metatable just as with userdata. A metatable allows you to hook table/uservalue key accesses and process them in C++.

You can use Lua's light user data to do that. In that case, the object is managed by C++ :
extern "C" int PassObjToLua(lua_State *L)
{
Measure * m=new Measure(); // I need to pass this object to Lua
lua_pushlightuserdata (L, m);
return 1;
}
extern "C" int GetObjFromLua(lua_State *L)
{
Measure *m = (Measure*)lua_touserdata (L, 1);
return 0;
}
To register your C functions in the Lua context :
lua_pushcfunction (L, GetObjFromLua);
lua_setglobal (L, "GetObjFromLua");
lua_pushcfunction (L, PassObjToLua);
lua_setglobal (L, "PassObjToLua");

Lualib has a C interface, not a C++ one -- so without further ado, you'd have to generate extern C functions that you can use with Lua.
The place here is far too short to give you a complete introduction on how to use C++ with lua, or evn how to extend a C program with Lua. I think it's safe to say you will find a tutorial that fits exactly your needs when you use google with lua C interface.
EDIT: Here's a screenshot of my google search. How much more ridiculous can we get?

Related

How to expose C++ unions to Lua

For a project I'm working on, I need to expose some C++ classes in another library to Lua. Unfortunately, one of the most important classes in this library has lots of Unions and Enums (the sf::Event class from SFML), and from a quick Google search I've discovered there is nothing on exposing C++ Unions to Lua. I don't mind if it's being exposed with the Lua/C API, with a library or with a binding generator, as long as it works. But, I'd prefer not to use a binding generator, because I want to be able to create an object in C++, then expose that instance of the object to Lua (unless that's possible with a binding generator)
For registering C/C++ functions you need to first make your function look like a standard C function pattern which Lua provides:
extern "C" int MyFunc(lua_State* L)
{
int a = lua_tointeger(L, 1); // First argument
int b = lua_tointeger(L, 2); // Second argument
int result = a + b;
lua_pushinteger(L, result);
return 1; // Count of returned values
}
Every function that needs to be registered in Lua should follow this pattern. Return type of int , single parameter of lua_State* L. And count of returned values.
Then, you need to register it in Lua's register table so you can expose it to your script's context:
lua_register(L, "MyFunc", MyFunc);
For registering simple variables you can write this:
lua_pushinteger(L, 10);
lua_setglobal(L, "MyVar");
After that, you're able to call your function from a Lua script. Keep in mind that you should register all of your objects before running any script with that specific Lua state that you've used to register them.
In Lua:
print(MyFunc(10, MyVar))
Result:
20
I guess this could help you!
If you are willing to use boost::variant rather than a union, you could try using my LuaCast library.
I'll try to add unions as a base type as well.

Call C++ Functions in an active program from Lua

I'm not sure if my question makes any sense, but I certainly know it is near impossible to get the results from Google. Firstly, what I do not want. I don't want to call some function that prints "hello world" or adds two numbers together, I want to load a Lua script from a C++ program, but allow the script to modify variables of the C++ program, using functions. For example, imagine I have a C++ program like this:
class Foo
{
private:
int number = 0;
public:
void setNumber(const int& newNumber) {number = newNumber;}
}
int main()
{
Foo foo;
//Load and execute Lua script, with foo object
return 0;
}
How could I allow the Lua script to do foo.setNumber() (preferably without foo.)? This may be a very simple question, but as mentioned above, almost all information on Google when searching "Call C++ Function from Lua" assume there is no program, but just a .cpp/hpp file with some functions that you want to call.
I'm on Linux (Ubuntu), but the program needs to compile on all platforms (Windows and Mac)
This is asked here fairly regularly.
To roll your own binding you should:
Master Lua metatables completely.
Read the Programming in Lua stuff on the C API, particularly the part on classes. Alternatively you can read the manual, read the source (API headers especially), and do some googling, but the book will probably save you some time.
Broadly, you expose a C++ class instance to Lua by creating a Lua "userdata" containing a pointer to the class instance and passing this to the Lua script. A userdata is an opaque type; the Lua script can't actually do anything with it (other than pass it around) unless you give it a metatable. At the very least you must implement the __index metamethod on the userdata, which allows your C++ code to intercept attempts to index the userdata and return something meaningful, and the __gc metamethod, which allows your C++ code to delete the exposed C++ object when the corresponding Lua userdata is garbage collected.
For instance, you create a function called createFoo which creates a Foo instance, wraps the pointer as a userdata, applies a metatable implementing __index to it, and returns it to the Lua script.
When the user runs foo.setNumber, your C++ __index metamethod is called with the userdata and the string "setNumber". It's up to you what you return and this determines what foo.setNumber evaluates to in the Lua script. You want foo.setNumber to evaluate to a lua_CFunction which expects a Foo userdata as its first parameter, so that your class methods can be called idiomatically from Lua (i.e. foo:setNumber(12), which is syntax sugar for foo.setNumber(foo, 12)).
It's a very low level and manual process, and once you get the hang of it you're going to end up create a library/templates/macros whatever to do the boilerplate for you. At that point you may want to evaluate the myriad C++ binding libraries that exist. However, thanks to the Law of Leaky Abstractions it's a very good idea to learn to do this manually first.

Pass C++ object to Lua function

I have a C++ project, where 1 method of a 1 class changes very often. So I want to take that code from C++ to Lua. Note, I'm novice to Lua.
The whole task:
Bind some class methods to Lua state machine;
Pass reference to class object to a function, written in Lua;
Operate with passed C++ object in Lua function.
I've found how to make first step with Lunar, and can't cope with second and third.
I can't use SWIG and boost.
//This has a large number of steps, but I'm gonna post them all. This is all using native Lua 5 and the lua CAPI.
int CreateInstanceOfT(lua_State* L) {
new (lua_newuserdata(L, sizeof(T))) T(constructor args);
return 1;
}
int CallSomeFuncOnT(lua_State* L) {
if (lua_istable(L, 1)) { // If we're passed a table, get CData
lua_getfield(L, 1, "CData");
lua_replace(L, 1);
}
if (!lua_touserdata(L, 1))
lua_error(L); // longjmp out.
T& ref = *(T*)lua_touserdata(L, 1);
ref.SomeFunc(); // If you want args, I'll assume that you can pass them yourself
return 0;
}
int main() {
lua_State* L = luaL_newstate();
lua_pushcfunction(L, CreateInstanceOfT);
lua_setglobal(L, "CreateInstanceOfT");
lua_pushcfunction(L, CallSomeFuncOnT);
lua_setglobal(L, "CallSomeFuncOnT");
luaL_dofile(L, "something.lua");
lua_close(L);
}
-- Accompanying Lua code: semicolons are optional but I do out of habit. In something.lua
function CreateCInstance()
local Instance = {
CData = CreateInstanceOfT();
SomeFunc = CallSomeFuncOnT;
}
return Instance;
end
local object = CreateCInstance();
object:SomeFunc(); // Calls somefunc.
I could post a great quantity of detail about how to make exposure easier, and how to make inheritance, and suchlike - and it'll need altering if you want to expose more than one T (I think the most common solution is a simple struct { std::auto_ptr<void>, int type } deal). But, it should be a starting point if you don't understand anything about this process.
Bascally, first, we ask Lua to allocate some space (the userdata), then put T in it. When CallSomeFuncOnT comes up, first we ask it if we have a table (many Lua classes are based around tables, as they support object orientation, metatables, and such), and get the userdata out, which we then convert into a pointer to our object, and then convert into a reference. Remember that lua_touserdata gives you a void*, so you'd better be damn sure about what's on the other end. Then we call somefunc and return.
In Main, we just register the functions as globals.
Now, in Lua, when you call CreateInstanceOfT, it effectively just calls the T constructor, transparently to the Lua user. Then we ditch it in a table, which is simpler for Lua novices, and call SomeFunc by passing it this table.
Have you taken a look at luabind? It makes it fairly easy to expose C++ objects and functions to LUA.
Like John, I've used luabind and recommend it. However, since using boost isn't an option for you, you may find the list of libraries on this page helpful. You may also want to check out the DoItYourselfCppBinding page on the lua-users wiki.
One library mentioned on the page is oolua, which has no dependencies (so it says).

Wrapping a Lua object for use in C++ with SWIG

Currently I know how to have C++ objects instantiated and passed around in Lua using SWIG bindings, what I need is the reverse.
I am using Lua & C++ & SWIG.
I have interfaces in C++ and objects in lua, that implement methods which do the same job and have the same structure. I would like to be able to instantiate these objects in lua yet pass them around in C++ using pointers to that interface which they resemble.
As such I can imagine creating a c++ implementation of the interface which would act as a handler for said lua object, yet I don't know how to do this. The class would act as the lua objects representative or proxy in the C++ world.
To clarify I shall start with the following example code used in an answer to a similar question I asked:
C++ code:
// Represents a generic bank account
class Account {
virtual void deposit(double amount) = 0;
};
Lua code:
SavingsAccount = { balance = 0 }
SavingsAccount.deposit = function(amount)
SavingsAccount.balance = SavingsAccount.balance + amount
end
-- Usage
a = SavingsAccount
a.balance = 100
a.deposit(1000)
Now say that I have a class in C++ called Bank:
class Bank {
void AddAccount(Account* a);
};
What I would like here is a mechanism for doing the following in lua:
SavingsAccount = { balance = 0 }
SavingsAccount.deposit = function(amount)
SavingsAccount.balance = SavingsAccount.balance + amount
end
-- Usage
a = SavingsAccount
bank:AddAccount(a)
If I need to take an extra step such as instantiating a C++ class to act as a proxy and pass it the lua table with all my lua functions etc, I can imagine it looking like this:
C++ code:
// Represents a generic bank account
class ProxyAccount : public Account {
virtual void deposit(double amount);
};
Lua code:
SavingsAccount = { balance = 0 }
SavingsAccount.deposit = function(amount)
SavingsAccount.balance = SavingsAccount.balance + amount
end
-- Usage
a = SavingsAccount
a.balance = 100
a.deposit(1000)
proxy = program.ProxyAccount()
proxy.settable(a)
bank:AddAccount(p)
The problem here being I have no idea how I would implement the ProxyAccount class, or even what the function signature of settable would look like...
I'm not familiar with SWIG (I know what it is but have never used it) so this may not be the answer you are looking for.
I've been working on a C++ project and have had success using luabind. It allows you to subclass C++ objects with Lua objects. You might want to give it a try and see if it works for you.
What I seem to gather from your examples and the discussions is that you are expecting Lua to be the primary language, and C++ to be the client. The problem is, that the Lua C interface is not designed to work like that, Lua is meant to be the client, and all the hard work is meant to be written in C so that Lua can call it effortlessly.
Now, the important question is: why don't you want to have a C representation of the object, and prefer to have it in Lua? Since C++ is a much lower level language, and object definitions must be static, and Lua dynamically defines its "objects" it is much easier to have Lua adapt to C++ objects.
Another issue I see is that you seem to be designing your Lua code in a very Object Oriented manner. Remember that even though Lua can fake Object Oriented concepts, it is not built as an Object Oriented language, and should not be used primarily as one. If you want a fully OO scripting language, use python instead.
Now if you Really want to do it the other way, and considered that the other alternatives do not work for you, then what I would recommend, is that you keep the Lua object as a coroutine, this will allow you to:
Keep a representation of the object
in C++ (the lua_State *)
Have multiple individual instances of the same "object type"
Lua takes care of the cleanup
However, the downsides are:
All functions that act on an "object"
need to do so through the lua API
There is no easy/fast way to recognize different lua types (you
could use a metatable)
Implementation is quite cumbersome, and hard to decypher.
EDIT:
Here is how you could expose the interface to an object in a script, Each object instance would be running a new lua_State, and run its script individually, thus allowing for your "Object member data" to just be globals inside the script instance. Implementing the API for the object's methods would go like this:
int move(lua_State * L)
{
int idx = lua_getglobal(L, "this");
assert(!lua_isnull(-1));
AIObject * obj = static_cast<AIObject *>(lua_touserdata(L, -1));
lua_pop(1);
//Pop the other parameters
obj->move(/*params*/);
}
You can bind any C function you want to Lua and call it from there. You can define in this function what you expect the contract is between your script and your C++ code. For example, the following would kind of do what you want. You'll need to add meta table information to your Lua tables so you can distinguish different Lua object types.
int lua_AddBankAccount(lua_State* L, int pos)
{
// Assume you've created metadata for your Lua objects.
if (IsAccount(L, pos))
{
// process your 'Account' Lua instance.
}
else
{
// error - tried to add a non-Account.
}
}
You can take this further with SWIG to bind any arbitrary C method, but it's basically the same.

A function expects a C++ object of abstract type A. How do I pass it a Lua object of an A subclass?

I'd like to pass to a function expecting a C++ object of a pure virtual class a Lua object of a class that derives from the pure virtual C++ class. How can I do this?
I'm new to lua and luabind so bear with me.
In C++:
struct A {
virtual void foo() = 0;
};
void do_something(A* a) {
a->foo();
}
In Lua:
class 'MyA' (A)
....
function MyA:foo()
print('hi')
end
In C++ again:
... // somehow create an instance of MyA class and named myA
// How?
// Maybe the result of a call to "MyA()"?
do_something(myA);
You would have to create a C++ class which implements your pure virtual function, then calls the Lua code. The implementation would be too complicated to just throw in here.
Basic pseudo code:
// C++
struct LuaA : public A
{
LuaA(const std::string &luacode)
: myLuaHandler(luacode)
{
}
virtual void foo()
{
myLuaHandler.call("MyA:foo()");
}
}
That example is very high level, but it's meant to show that what you want to do is non-trivial. It's the new "LuaA" that you would want to actually expose to your Lua code.
In general I prefer to use SWIG when wrapping my C++ for exposure to Lua and other scripted languages. SWIG does support this overloading of virtual methods that you are interested in (called "directors" in SWIG parlance), however, it should be noted that Lua/SWIG does not support directors. Java, C#, Ruby, Perl and Python do all have directors support in SWIG. I'm uncertain as to exactly why it is not supported in Lua.
It is possible, that since Lua does not support inheritance, the exact semantics of what you would like to accomplish are simply not possible in the way you propose.
Perhaps someone else has a better answer to the Lua side of things?
See section 10.1 in the LuaBind documentation. You basically provide a simple C++ wrapper to the LuaBind class that acts as a pass through to the underlying Lua implementation. Notice the following from this doc:
virtual void f(int a)
{
call<void>("f", a);
}
call("f", a) will invoke the Lua 'f' function, passing in the argument a.
Sorry, I would not answer the question you've asked directly, but will offer a bit of advice from personal experience instead:
If you're new to Lua, you should seriously consider writing your first bindings in raw Lua API and without such object-oriented layout. At least you will understand what is really going on.
Lua API is quite comfortable to use by itself. It does not create any extra overhead and you're in full control on what is happening. Luabind library development is a bit stale at the moment (but it looks like it comes back to life though).
You should consider if you really need to imitate deriving from C++ classes in Lua-side and, especially, on C++-side. Such thing is not-so-natural for Lua and requires noticeable overhead to be implemented. Furthermore, in C++ you're hiding the fact that you're making a non-native call to another language. Unless well documented, this is a potential source for performance issues.
When I've started working with Lua a few years ago, I've used to write bindings in the same way as you do, with Luabind, and imitating deriving from C++ objects. Now I'm using pure Lua API and simplistic procedural (as opposed to object-oriented) cross-language interface. I'm a lot happier with the result.
I will subclass the pure virtual class in C++ and then likely start with luabind (as per Aaron and lefticus' solutions). If this overhead is too great, I will just use the straight Lua C stack-twiddling API (as per Alexander).
Thus, there's no one answer here. I will post a comments with results later.
Thanks everyone!