我正在使用userdata在Lua中传递metatables并调用c ++。我想知道是否轻量级用户数据可以帮助我处理一些我遇到的问题。
轻用户数据是一个空*,但你不能在lua中做任何事情,至少我理解你可以通过函数调用将它传递给C并以某种方式返回到C?
如何使用轻型用户数据?如果有人有一些使用案例他们已经使用过它会帮助我解决它们。
TIA
答案 0 :(得分:3)
我认为Programming In Lua解释得很清楚:
light userdata的真正用途来自平等。由于完整的userdata是一个对象,它只等于它自己。另一方面,轻用户数据表示C指针值。因此,它等于表示相同指针的任何userdata。因此,我们可以使用light userdata在Lua中找到C对象。
作为一个典型的例子,假设我们正在实现之间的绑定 Lua和一个Window系统。在此绑定中,我们使用完整的userdata 代表窗户。 (每个userdatum可能包含整个窗口 结构或只是指向系统创建的窗口的指针。)何时 在窗口内有一个事件(例如,鼠标点击),系统 调用特定的回调,通过其地址识别窗口。至 将回调传递给Lua,我们必须找到代表的userdata 给定的窗口。要找到这个用户数据,我们可以保留一个表格 索引是带有窗口地址和值的轻用户数据 是完整的用户数据,代表Lua中的窗口。一旦我们有了 一个窗口地址,我们将它作为轻量级用户数据推送到API堆栈中 并使用userdata作为该表的索引。 (注意表 应该有弱值。否则,那些完整的用户数据将永远不会 收集。)
该页面还解释了轻量级用户数据不是垃圾回收,因此内存管理必须由您的代码完成。在我看来,用例实际上相当有限,这可能是你找不到很多例子的原因。我找到了one example:
我有一个从lua构造一个gui对象(树视图)的例程 表。然后我有一个由窗口句柄索引的单独的lua表 每个树节点,作为lightuserdata。这简化了c / lua 接口 - 我可以使用c句柄查找相应的lua表 对象
// save a window handle
lua_pushlightuserdata(L, hKey);
lua_pushvalue(L,filt); // copy of filter table entry
lua_settable(L, treeindex);
// find data for a window handle
lua_pushstring(L, "__treeitems");
lua_gettable(L, LUA_GLOBALSINDEX);
lua_pushlightuserdata(L, hKey);
lua_gettable(L, -2);
答案 1 :(得分:1)
一个典型的用例是当你将lua嵌入到另一个应用程序中时,你想给lua作者提供令牌(以轻量级用户数据的形式),它们可以传递给你设置的API。这是一个具体的例子。
假设您在lua中为人和朋友提供了以下API:
这些可以让您通过绑定访问“朋友”对象
GetPersonCount() // returns a number
GetPerson(index) // returns a light user data - a pointer to the C++ version
这些将获取GetPerson(或下面的GetFriend)的返回值作为参数。
GetFirstName(person)
GetLastName(person)
GetFriendCount(person)
GetFriend(person, index) // would also return user data like GetPerson
如果您已经使用C ++构建了一个用于获取有关朋友的信息的程序,那么这将非常有用,但是您希望通过一个可以在运行时安全访问的更简单有限的界面让人们可以在lua中编写脚本无需编译或源代码。