Comments (12)
Thanks for the support !
Will try to answer the questions one by one.
- When pushing a C++ pointer to Lua is it possible to dynamically choose what exposed class to use?
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
and class B : public A
(as derivedClass from A) then it's possible you dynamic_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-objects for more info on how to recreate your C++ class hierarchies to be exposed to lua.
- Can C++ exposed classes be extended in 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 addIndexMetamethod
and addNewIndexMetamethod
which allows to expose a C++ class via beginClass
and still overload __index
and ___newindex
lua metamethods to store and retrieve "dynamic" parameters (you should write the storage yourself in C++). https://kunitoki.github.io/LuaBridge3/Manual#27---index-and-new-index-metamethods-fallback
- Security on possible malicious Lua scripts.
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 getNamespaceFromStack
in order to have separate env tables for each lua thread (coroutine). So a script running in a lua thread can see only what is exposed in that env table, instead of the global namespace, also a global variable in the env will not leak into the global namespace and interfere with other coroutines.
See > https://github.com/kunitoki/LuaBridge3/blob/master/Tests/Source/CoroutineTests.cpp#L82
- What are your future plans with LuaBridge3?
Some things on the roadmap are explicited here #54 (comment)
from luabridge3.
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:
I am writing a Lua wrapper around a pretty big library. The library itself manages all allocation of objects and it's lifetime with a garbage collector. It is impossible to modify the existing library's classes to use RefCountedObjectPtr
. I also don't really want to let Lua control the lifetime at all.
So what I did was adding a special version of the class Userdata
. Instead of void* m_p
I am storing a weak reference to the library objects. Furthermore I've modified all function and property calls from and to Lua to check whether the weak ref is still alive. If it was collected by the GC and is dead a Lua error is thrown.
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.
from luabridge3.
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:
- you have the lightuserdata in Lua
- query the table, got the object in Lua
- use the object on the Lua side, which calls back into C++
- some C++ callback triggers the garbage collector which deletes the object
- use again the previously used object in Lua
- boom!
from luabridge3.
To get back on the index extension feature.
-
Are the
add*MetaMethod
functions called on derived classes when it's registered on the base class? -
When using your example it sometime crashes when trying call a value as a function.
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);
}
Assertion failed: equalstates(L, m_L) [LuaBridge.h] [Line: 6530]
lua_topointer() []
std::_Hash<std::_Umap_traits<luabridge::LuaRef,luabridge::LuaRef,std::_Uhash_compare<luabridge::LuaRef,std::hash<luabridge::LuaRef>,std::equal_to<luabridge::LuaRef> >,std::allocator<std::pair<luabridge::LuaRef const ,luabridge::LuaR()
indexMetaMethodFunction2() [LuaTest.cpp:558]
luabridge::detail::invoke_proxy_function<luabridge::LuaRef (__cdecl*)(MyVector &,luabridge::LuaRef const &,lua_State *)>() [LuaBridge.h:5949]
lua_yieldk()
luaD_precall()
luaM_toobig()
lua_callk()
luabridge::detail::index_metamethod() [LuaBridge.h:5497]
from luabridge3.
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
from luabridge3.
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 addIndexMetaMethod
must be registered on the base class and won't work if it is registered in a derivedClass
right? If so you should add that to the docs please.
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 bc
.
from luabridge3.
It is normal, as you are calling via :
the first argument is self, so you need to add that explicitly in the function signature
from luabridge3.
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).
from luabridge3.
Take a look here http://tpcg.io/_2N67Y8
from luabridge3.
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)
from luabridge3.
I don't get it, in lua this:
object:func(1)
will be rewritten as
object.func(object, 1)
from luabridge3.
Sorry for the confusion, you are absolutely right.
from luabridge3.
Related Issues (20)
- Enhancement Request: Custom error function for `lua_pcall`. HOT 11
- Error C3861 (using with Luau) HOT 3
- Can I cast types inside Lua? HOT 4
- Duplicate symbols on Win32 with default __stdcall HOT 9
- Debug names of C functions for Luau HOT 8
- Extensible class bug with inheritance
- Add support for addStaticIndexMetamethod and addStaticNewIndexMetamethod
- Using LuaBridge3 in a precompiled header on MSVC leads to an internal compiler error HOT 2
- Use of std::shared_ptr on classes without `std::enable_shared_from_this` HOT 1
- Stateful lambdas registered as functions loose state HOT 2
- Compile error with Cfunc property getter/setter HOT 2
- std::vector to 0-based Lua table HOT 5
- MSC Warning C4146 HOT 2
- How to expose C++ data (a vector, in this case) to Lua without making a copy? HOT 2
- Does LuaBridge3 Support Android for SDL2-based Games? HOT 2
- Passing a Lua Table (LuaRef) as an argument to C++ function HOT 1
- How to get the name of a Lua variable? HOT 2
- Comparison Issue Between `uint64_t` in C++ and Numeric Constant in Lua HOT 8
- NAI run lua code in string from cpp
- Explicit inclusion of `#include <stdint.h>`. HOT 1
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from luabridge3.