在C中处理这个问题的最佳方法是什么?我猜我需要在C中编写一个函数来注册为__index并以某种方式处理它.也许检查密钥是否属于Lua方法表,如果是,则调用它.
任何帮助/提示将不胜感激.我没有找到这样的例子,虽然这对我来说似乎是很自然的事情.
编辑:在Lua中添加了我的C版解决方案,在下面的答案中发布.这或多或少都是直接翻译,所以所有功劳都归功于@ gilles-gregoire.
以下C函数注册为__index元方法.
static int perml_index(lua_State *L) { struct perm **pp = luaL_checkudata(L,1,PERM_MT); int i; luaL_getMetatable(L,PERM_MT); lua_pushvalue(L,2); lua_rawget(L,-2); if ( lua_isnil(L,-1) ) { /* found no method,so get value from userdata. */ i = luaL_checkint(L,2); luaL_argcheck(L,1 <= i && i <= (*pp)->n,2,"index out of range"); lua_pushinteger(L,(*pp)->v[i-1]); }; return 1;};
这是执行此 *** 作的代码,
int luaopen_perm(lua_State *L) { luaL_newMetatable(L,PERM_MT); luaL_setfuncs(L,perml_methods,0); luaL_setfuncs(L,perml_functions,0); lua_pop(L,1); luaL_newlib(L,perml_functions); return 1;};
其中perml_methods是
static const struct luaL_Reg perml_methods[] = { { "__index",perml_index },{ "__eq",perml_equal },{ "__tostring",perml_tostring },{ "__gc",perml_destroy },[...] { NulL,NulL }};
和perml_functions是
static const struct luaL_Reg perml_functions[] = { { "inverse",perml_new_inverse },{ "product",perml_new_product },{ "composition",perml_new_composition },NulL }};解决方法 这看起来像一个可以用嵌套元表解决的问题.你需要一个Metatable用于方法(比如你的sort()方法),第二个用于索引 *** 作.第二个Metatable实际上是Metatable方法的Metatable.
让我把它写成lua代码.你需要3个表:
-- the userdata object. I'm using a table here,-- but it will work the same with a C userdatau = {}-- the "methods" Metatable:mt = {sort = function() print('sorting...') end}-- the "operators" Metatable:op_mt = {__index = function() print('get') end}
现在,棘手的部分就在这里:当你调用一个方法时,lua会首先查找你.
如果它找不到它,它将在你的Metatable的__index字段指向的表中查找…而Lua将重复该表的进程!
-- first level Metatablemt.__index = mtsetMetatable(u,mt)-- second level MetatablesetMetatable(mt,op_mt)
你现在可以像这样使用你的:
> u:sort()sorting...> = u[1]getnil
编辑:通过使用__index元方法的函数更好的解决方案
使用__index元方法的函数可能是正确的方法:
u = {}mt = {sort = function() print('sorting...') end}setMetatable(u,mt)mt.__index = function(t,key) -- use rawget to avoID recursion local mt_val = rawget(mt,key) if mt_val ~=nil then return mt_val else print('this is a get on object',t) endend
用法:
> print(u)table: 0x7fb1eb601c30> u:sort()sorting...> = u[1]this is a get on object table: 0x7fb1eb601c30nil>总结
以上是内存溢出为你收集整理的Lua userdata数组访问和方法全部内容,希望文章能够帮你解决Lua userdata数组访问和方法所遇到的程序开发问题。
如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)