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

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.

Related

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

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?

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.

C++ Expose Already Existing Instance of Objects to a Scripting Language

So, I want to be able to modify already instanced C++ objects in a scripting language. I have been looking at Lua with LuaBind and Python with SWIG or Boost::Python, but all I see is how to make new instances of the objects, but I want to modify already existing ones.
Example:
C++:
Player playerOne = new Player();
Scripting Language :
playerOne.Transform.x += 5;
Is this possible, and if so, wat would you suggest as a good Language/library to achieve this with?
In my main project we use LuaBind, and it works pretty well. We do basically what you're asking to do. We have existing C++ objects where we want behavior extended in various ways, but it would be a lot of work and risky to do those changes in behavior in the C++ code for the object itself.
So in your example, you'd want at least 2 C++ wrapper classes - one that represents the 'Game' that allows you to write an API function to return players, and a wrapper class that wraps the C++ player class that you can return to lua. Each wrapper function would have api functions/properties that would fiddle with the individual object it's wrapped internally that lua could call and pass values to. Here is a link to an article giving you pretty straightforward examples of using LuaBind and what it looks like:
http://blog.nuclex-games.com/tutorials/cxx/luabind-introduction/
I recently needed to do the same thing. I also considered (and used) Boost.Python but personally (as much as I love Boost) I felt it was a little overkill to drag in half the Boost library to get one feature.
So, if you're interested, I recently implemented a very light-weight Python wrapper library called ECS:Python. ECS:Python (Embedded C++ Scripting with Python) is designed specifically for C++ developers that wish to expose objects FROM a C++ application TO an embedded Python interpreter for interactive scripting.
Its free (BSD) and open source: http://sourceforge.net/projects/ecspython
There is no mechanism that can magic values into a scripting language from the host language. If you want a particular object instances to be accessible in the scripting language, it must be given to the scripting language via some function.
This is no different from any other properly encapsulated C++ type. If object A creates and stores some instance T, then the only way object B can get it is if it calls a function on A that returns T.
I was having the problems in my project. Have a look at my post in the Ogre3d forums:
http://www.ogre3d.org/forums/viewtopic.php?f=5&t=41631&p=332200&hilit=mrmclovin#p405204
Code example:
int main (int argc, char * const argv[])
{
try
{
// Initialize the python interpreter
Py_Initialize();
// Create a module dynamically
object module((handle<>(borrowed(PyImport_AddModule("NameOfMyModule")))));
// Retrieve the module's namespace
object main_namespace(module.attr("__dict__"));
// Put a c++ class named "Car" exported using boost.python into our module
main_namespace["Car"] = class_<Car>("Car")
.def("drive", &Car::drive)......;
// The class car now exists in a dynamic module
// and that module is accessable everywhere as longs as the python interpreter exists
// Create a instance of Car here
Car* myCar = new Car(...);
// Now simply add it to the module. Make sure you have exposed class Car before adding instances
main_namespace["car_instance"] = object(ptr(myCar)); // the boost python ptr() class make sure not to copy the pointee but only copy pointer adress
}
catch( error_already_set )
{
PyErr_Print();
}
return 0;
}

How would I go about sharing variables in a C++ class with Lua?

I'm fairly new to Lua, I've been working on trying to implement Lua scripting for logic in a Game Engine I'm putting together. I've had no trouble so far getting Lua up and running through the engine, and I'm able to call Lua functions from C and C functions from Lua.
The way the engine works now, each Object class contains a set of variables that the engine can quickly iterate over to draw or process for physics. While game objects all need to access and manipulate these variables in order for the Game Engine itself to see any changes, they are free to create their own variables, a Lua is exceedingly flexible about this so I don't forsee any issues.
Anyway, currently the Game Engine side of things are sitting in C land, and I really want them to stay there for performance reasons. So in an ideal world, when spawning a new game object, I'd need to be able to give Lua read/write access to this standard set of variables as part of the Lua object's base class, which its game logic could then proceed to run wild with.
So far, I'm keeping two separate tables of objects in place-- Lua spawns a new game object which adds itself to a numerically indexed global table of objects, and then proceeds to call a C++ function, which creates a new GameObject class and registers the Lua index (an int) with the class. So far so good, C++ functions can now see the Lua object and easily perform operations or call functions in Lua land using dostring.
What I need to do now is take the C++ variables, part of the GameObject class, and expose them to Lua, and this is where google is failing me. I've encountered a very nice method here which details the process using tags, but I've read that this method is deprecated in favor of metatables.
What is the ideal way to accomplish this? Is it worth the hassle of learning how to pass class definitions around using libBind or some equivalent method, or is there a simple way I can just register each variable (once, at spawn time) with the global lua object? What's the "current" best way to do this, as of Lua 5.1.4?
One approach is to use
a lightuserdata pointing to the C++ variable
a C function to access the C++ variable using the lightuserdata
keep the lightuserdata as an upvalue of the C function so one function suffices for all variables
use the number of arguments to the function to select between getting and setting the variable
For example:
int game_state_var_accessor (lua_State *L)
{
int *p = lua_topointer(L, lua_upvalueindex(1));
if (lua_gettop(L) == 0)
{ // stack empty, so get
lua_pushinteger(L, *p);
return 1;
}
else
{ // arg provided, so set
*p = lua_tointeger(L,1);
return 0;
}
}
When you make a new game state you can create accessors for each variable using:
lua_pushlightuserdata(L, (int *)p); // where p points to your variable
lua_pushcclosure(L, game_state_var_accessor, 1);
The accessor is now on the stack and can be bound to a global name, or to the name of a method in a Lua class. If your Lua class table is on the stack at index t this would be:
lua_setfield(L, t, "name_of_accessor");

Implementing and inheriting from C++ classes in Lua using SWIG

Would it be possible using Lua and SWIG and say an IInterface class, to implement that interface and instantiate it all within Lua? If so how would it be done?
In the first place, C++ style interfaces does now make much sense in a language like Lua. For a Lua object to conform to an interface, it just need to contain definitions for all the functions in that interface. There is no need for any specific inheritance. For instance, if you have a C++ interface like this:
// Represents a generic bank account
class Account {
virtual void deposit(double amount) = 0;
};
you can implement it in Lua without any specific inheritance specifications:
SavingsAccount = { balance = 0 }
SavingsAccount.deposit = function(amount)
SavingsAccount.balance = SavingsAccount.balance + amount
end
-- Usage
a = SavingsAccount
a.balance = 100
a.deposit(1000)
In short, you don't need the C++ interface. If you need to extend the functionality of a C++ class from Lua, you should wrap that into a Lua object as described here and do "metatable" inheritance as explained here. Also read the section on Object Oriented Programming in the Lua manual.
Store the table in a c++ class by holding a pointer to the lua state, and the reference returned for the table as specified using this API:
http://www.lua.org/pil/27.3.2.html
Then when a method on the wrapper class is called, push the referenced object onto the stack and do the necessary function call