LuaBridge
LuaBridge copied to clipboard
addCFunction in 3rd party class
This library is just awesome but it seems that I'm overseeing something on this simple problem.
I have a class from a third party library which cannot be modified at all. I'm exposing this class with the usual beginClass. Now I'd like to use addCFunction on this class but I cannot do that because it only accepts class member functions. std::function also doesn't work here.
.addCFunction("MyCustomFunc", std::function<int(lua_State*)>([](lua_State* L) {
luabridge::push(L, 1337);
luabridge::push(L, 3.1415);
return 2;
}))
How can I add a C function with lua_State and custom return values to my class which cannot be modified?
Thank you!
If you use addCFunction, you need to make sure you provide a lua_CFunction:
int myCFunction(lua_State*) { return 0; }
.addCFunction("MyCustomFunc", &myCFunction))
or eventually decay a lambda to a function pointer
.addCFunction("MyCustomFunc", +[](lua_State*) -> int { return 0; })
Your first suggestion does not work. Because the class on which I want to do addCFunction cannot be modified. It's a 3rd party class. So when I do what you wrote it gives an error.
cannot convert argument 2 from 'int (__cdecl *)(lua_State *)' to 'int (__cdecl NameOfThe3dPartyClass::* )(lua_State *)'
The second suggestion with the lambda does not work as well for the same reason.
What luabridge is missing here is a specialization for addCFunction where the bound function is not part of the class. Pretty much a "function member proxy" like for normal non-CFunctions as described here. http://vinniefalco.github.io/LuaBridge/Manual.html#s2.5
You are right, i thought this was also in vanilla luabridge, but this is only possible with luabridge3. can't you use a normal function ?
.addFunction("MyCustomFunc", +[](MyClass* self, lua_State* L) { })
In luabridge3, addCfunction disappeared and i added support for generic CFunction with self object on top of the stack, see https://github.com/kunitoki/LuaBridge3/blob/master/Source/LuaBridge/detail/Namespace.h#L978-L998
An example usage:
struct MyClass {};
int cFunctionMethod(lua_State* L)
{
auto ref = luabridge::LuaRef::fromStack(L, 1);
if (!ref.isUserdata() || !ref.isInstance<MyClass>()) {
return 0;
}
auto arg = luabridge::LuaRef::fromStack(L, 2);
if (!arg.isNumber()) {
return 0;
}
std::error_code ec;
luabridge::push(L, arg.cast<int>() + 1000, ec);
return 1;
}
luabridge::getGlobalNamespace(L)
.beginClass<MyClass>("MyClass")
.addFunction("method", &cFunctionMethod)
.endClass();
runLua("result = MyClass():method(1000)");
ASSERT_EQ(2000, result<int>());
@kunitoki Nice, is it possible to use that piece of code in the "official" luabridge?
Yeah, not pretty but you can "hack it" somehow registering a static function to your class with addStaticFunction but call it with : instead of .
Ok, let me implement this :)