-
Thank you for your work on this project. I have some questions and would be very thankful to have some answers. Let's assume I have exposed multiple classes to Lua with LuaBridge3. They include simple structs like Vectors where lifetime is managed by Lua but also pointers to objects where the host manages lifetime. When pushing a C++ pointer to Lua is it possible to dynamically choose what exposed class to use?I often do not know the exact type at compile time. class A Let's say I have a pointer of type A but it's actually an instance of class B and I want to push the pointer as if it was B. I think it would require a dynamic database or something of the class keys in ClassInfo.h. Can C++ exposed classes be extended in Lua?I would like to add functions to C++ exposed classes in Lua. Ideally one could even override existing C++ functions and also call the function of the parent class. Security on possible malicious Lua scripts.Let's assume we only expose known safe functions to Lua and forbid bytecode. Did you do some research or tests on LuaBridge3 whether it is safe to run unknown Lua code. What are your future plans with LuaBridge3?Would be nice if you could share your plan on features etc. you might be working on in the future. Thank you again for your work and time. |
Beta Was this translation helpful? Give feedback.
Replies: 13 comments
-
Thanks for the support ! Will try to answer the questions one by one.
Yes, if the types have been registered with LuaBridge, than it's a matter of casting to your right type (the best cast depends on the usa case and object types, static or dynamic) before sending the pointer/reference into lua (via stack push or function calls from C++). So if you registered both See https://kunitoki.github.io/LuaBridge3/Manual#23---class-objects for more info on how to recreate your C++ class hierarchies to be exposed to lua.
Yes ! And only in LuaBridge3 (not in vanilla luabridge). For enabling that support, there is some boilerplate needed, but it will also allow better flexibility once you build one of such "extensible" classes. Have a look at the
I personally have a strict way to setup my environment, and i carefully select and block environments from exposing functions i do not want a scripter to use. But there is nothing in luabridge for that, you need to do it yourself in lua at the moment. Will try to see if i can extract some of these utils and make them part of the library. You could have a look at how i do coroutines sandboxed "envs" using LuaBridge3 See > https://github.com/kunitoki/LuaBridge3/blob/master/Tests/Source/CoroutineTests.cpp#L82
Some things on the roadmap are explicited here #54 (comment) |
Beta Was this translation helpful? Give feedback.
-
Thank you for the answer. I've read carefully through it. The ability to hook into __index sounds awesome. I am just in the process of migrating from the vanilla LB to LB3 here. Once that's done I will look into dynamic class extensions. I do have one more question tho: It's pretty ugly right now. So I was wondering if you know a better alternative. I've looked into ContainerTraits but that doesn't seem to work for me. I still need to be able to push and get raw pointers. |
Beta Was this translation helpful? Give feedback.
-
You could maybe look into having lightuserdata (http://www.lua.org/pil/28.5.html) to stored full userdata objects in a weak table in the registry (https://www.lua.org/pil/17.html), you only need to register and unregister your real C++ objects into this table, but then give away lightuserdata pointers indexes into the table. If you can find a lightuserdata into the weak table, then you could access the full userdata to it, and if you don't find it, object lifetime ended on the c++ side. The problem is what to do if your full userdata is garbage collected by C++ while you hold a local reference to it in lua:
|
Beta Was this translation helpful? Give feedback.
-
To get back on the index extension feature.
MyObject.abc = true
MyObject:abc()
MyObject:xyz() luabridge::LuaRef indexMetaMethodFunction2(MyVector& x, const luabridge::LuaRef& key, lua_State* L)
{
UE_LOG(LogTemp, Warning, TEXT("indexMetaMethodFunction"));
if (key.tostring() == "xyz")
{
if (!luabridge::push(L, "123"))
lua_pushnil(L);
}
else
{
auto it = data.find(key);
if (it != data.end())
return it->second;
lua_pushnil(L);
}
return luabridge::LuaRef::fromStack(L);
}
|
Beta Was this translation helpful? Give feedback.
-
Are you working with multiple lua threads (i see a call to yield from the stack trace) ? Beware of stored LuaRef in separate lua threads (coroutines) they have different lua_State pointers (that's why equalstates assertion fails). See if moving the reference to the current thread solves it https://github.com/kunitoki/LuaBridge3/blob/master/Distribution/LuaBridge/LuaBridge.h#L7062 |
Beta Was this translation helpful? Give feedback.
-
No but I was using a global variable and forgot to reset that. So a new luastate caused that problem. Anyway I think it is normal that Is it normal that when doing the following with your basic test code: local bc = MyBaseClass(3)
bc.test = function(Value) print("Value: ", Value); end
bc:test("ok") The test function will not print the string "ok" but it prints the userdata of |
Beta Was this translation helpful? Give feedback.
-
It is normal, as you are calling via |
Beta Was this translation helpful? Give feedback.
-
About the methods being used in derived classes i'm not sure that will work, i would keep it simple to avoid confusion when calling c++ methods or dynamic methods from lua (use one or the other). |
Beta Was this translation helpful? Give feedback.
-
Take a look here http://tpcg.io/_2N67Y8 |
Beta Was this translation helpful? Give feedback.
-
I am aksing because it is so inconsistent with Userdata. Because for normal registered Userdatas it's the opposite: MyUserdataObject:MyFunction(p1, p2, p3) or MyUserdataObject.MyFunction(MyUserdataObject, p1, p2, p3) |
Beta Was this translation helpful? Give feedback.
-
I don't get it, in lua this: object:func(1) will be rewritten as object.func(object, 1) |
Beta Was this translation helpful? Give feedback.
-
Sorry for the confusion, you are absolutely right. |
Beta Was this translation helpful? Give feedback.
-
I have extended classes in Lua by registering proxy functions. Those work in either LB2 or LB3, though LB2 (frustratingly) doesn't allow lambdas in all proxy situations. |
Beta Was this translation helpful? Give feedback.
Thanks for the support !
Will try to answer the questions one by one.
Yes, if the types have been registered with LuaBridge, than it's a matter of casting to your right type (the best cast depends on the usa case and object types, static or dynamic) before sending the pointer/reference into lua (via stack push or function calls from C++).
So if you registered both
class A
andclass B : public A
(as derivedClass from A) then it's possible youdynamic_cast<B*>(my_a_pointer)
in C++ and send it into luabridge, using normal RTTI in C++.See https://kunitoki.github.io/LuaBridge3/Manual#23---class…