Can we pass C++ object into Lua scrips - lua

I want to pass a C++ object to Lua and use the same object in Lua. I have seen example of creating C++ objects in Lua and use them. But I want to do like this below.
Create a C++ object in C++ code
Pass this to Lua scripts and get some return values.
I have gone through these examples here.
http://loadcode.blogspot.sg/2007/02/wrapping-c-classes-in-lua.html
https://gist.github.com/kizzx2/1594905
But they are creating C++ objects in Lua and using them in Lua scripts.
can you please give some pointers.

Given that you did read some userdata manuals, it is very easy to achieve that. The only diference is that in regular ud manual they create objects in Lua function and you already have an object. Just push new userdata of pointer size and set it's metatable to Lua class's metatable (which you prepared anyway).
void **ud;
ud = lua_newuserdata(L, sizeof(*ud));
*ud = object; // existing
luaL_getmetatable(L, tname);
lua_setmetatable(L, -2);
// ud at top of stack
lua_setglobal(L, "foo");
Where tname is your Lua-side classes metatable name.

As you don't want to use the objects within Lua (just pass them on to C++), you can wrap them as a lightuserdata (see here) from C++, and later just pop it (you may want to check if it is_lightuserdata before).

Related

Without knowing the userdata implementation, can I use its fields from inside C++?

I can obtain a userdata from inside my C++ code. I want to know if I can cast it to something so I can dereference its fields and invoke its methods without going through Lua.
In other words:
Once I obtain an userdata and put it in the Lua stack, how can I get it out and use it as an object of a certain class? I know all fields and methods that I'm interested in (their Lua names), but not necessarily all fields and method the userdata underlying implementation provides.
Is there a way to somehow create an interface that would know the offsets of each member?
I believe the question is, how do I know the offset of each member in the Lua view of the userdata, so I can create a struct to cast the void * returned by lua_touserdata to?
Userdata is just a binary blob. Array of bytes. How those bytes will be interpreted - depends entirely on interface provided with that userdata, be it metatable with methods, or some other agreements.
If that userdata created by your code, then you either know what type of native object is there (knowing that some func generate or accept only specific type), or you can place type identifier as first bytes of userdata blob, so you can check that id and switch/cast userdata pointer to a specific class.
If that userdata created by someone's code - you can only rely on methods provided within its metatable (you can access it from native code), or just treat is as array of bytes, without possibly knowing actual type of data stored there. Or do some hackish guesses, making it working in some cases, and crashing badly if your guess wasn't correct.

Create new empty userdata from pure Lua

I think I saw somewhere a native function in Lua that can return a new userdata. Does it exist? Is it possible to create custom userdata from normal Lua script?
You may be thinking of newproxy
From: http://lua-users.org/wiki/HiddenFeatures
newproxy is an unsupported and undocumented function in the Lua base
library. From Lua code, the setmetatable function may only be used
on objects of table type. The newproxy function circumvents that
limitation by creating a zero-size userdata and setting either a new,
empty metatable on it or using the metatable of another newproxy
instance. We are then free to modify the metatable from Lua. This is
the only way to create a proxy object from Lua which honors certain
metamethods, such as __len.
It was also useful for __gc metamethods, as a hack to get a callback when the newproxy instance becomes free.
This feature was present in Lua 5.1, but removed in 5.2. In Lua 5.2, __gc metamethods can be set on zero sized tables, so the main impetus for newproxy went away.
Actually no, in pure Lua.
The type userdata is provided to allow arbitrary C data to be stored in Lua variables. … Userdata values cannot be created or modified in Lua, only through the C API. This guarantees the integrity of data owned by the host program.
link
If you embed luaVM in host C/C++ application, you can export some function to create userdata to Lua, but it's not a good practice. UD is designed to be a blackbox for Lua scripts.

How to create userdata for C in Lua scripts

SWIG considers C's enum as userdata. (I checked the source it generated. Perhaps a bug?). Then, I need to create userdata inside the Lua scripts itself... Any good ways?
Then, I need to create userdata inside the Lua scripts itself.
No. You want to create one of the enumerator values within Lua. You do that pretty much as you would in C: use the enumerator's name. This is an object that has the value of the enumerator. However SWIG's Lua component decides to marshal this is irrelevant; just use the name in your Lua code.

need to assign a global as a pointer and use it in lua

I am using luabind and I want to make this lua code work.
print("hello..welcome to lua\n")
base:PrintMe("printing from base" )
From c++, I want to assign the lua global variable "base" as a pointer to "Base" class.
class Base {
public:
void PrintMe(const char *s) { ... }
};
Using Luabind I can bind the Base class. I am creating a Base class object in c++.
I want to push this pointer to lua and use it as lua global variable "base" as seen in the lua code above.
Can someone please help me, the most easiest way to do this (using luabind itself if possible) ??
I have tried pushing it as a lightuserdata, but the PrintMe is not getting called from lua.
This line will take care of the issue :)
globals(ls) ["base"] = baseObjPtr;

Lua bindings: table vs userdata

When making Lua bindings for C++ classes, should I return tables or userdata objects?
Does anyone know any of the pros and cons for each method?
I recommend returning userdata. Regardless of approach, there has to be somewhere to put the pointer
to the C++ data, or the actual C++ data itself, and there's nowhere
safe to do this with a table.
Returning tables would make sense in some situations, because they can
be 'annotated' in Lua with extra attributes without one's having to do
anything extra to support this. Unfortunately the C++ object pointer
has to go somewhere, and there's nowhere sensible for it to go other
than an actual entry in the table itself.
This is not a very safe place for it to go. It can be found by Lua
code, and removed or replaced. This could be by accident, or on
purpose, it doesn't really matter.
My preference therefore is to return userdata objects. They can be
made to work like tables if one really must insist upon that, but they
also have a "secret" area (the actual userdata itself) where the C++
object pointer can be stored, safe from overwriting by Lua code.
(Userdata objects also have an "environment" pointer, which is another
place to store object-specific data. As with the userdata payload
itself, this value is inaccessible to Lua code and can't be damaged
that way.)

Resources