我在C中寫了一個用於Lua的userdata類型。它有一些數組類型的屬性和各種方法。現在,如果你是這種類型,我使用u:set(k,v)
resp。 u:get(k)
訪問數據和例如作爲方法使用u:sort()
。爲此,我將__index
設置爲包含這些方法的表格。現在如果我想使用u[k] = v
或u[k]
訪問數據,我需要設置__newindex
和__index
至set
或get
。但其他方法不再可訪問...Lua userdata數組訪問和方法
在C中處理此問題的最佳方法是什麼?我猜我需要在C中編寫一個函數來註冊爲__index
,並以某種方式在那裏處理它。也許檢查鍵是否屬於Lua表的方法,如果是的話,調用它。
任何幫助/提示將不勝感激。我沒有找到像這樣的例子,雖然這似乎是很自然的事情(對我來說)。
編輯:在Lua中添加了我的C版本的解決方案,發佈在下面的答案中。這或多或少是一種直接的翻譯,所以所有功勞都歸於@吉列爾 - 格雷戈裏。
以下C函數被註冊爲__index metamethod。
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, NULL }
};
這似乎是一個合理的方法給我。 –
[Lua編程](http://www.lua.org/pil/28.2.html)有一個關於在C中創建數組類型的廣泛教程,包括在C中添加元方法。它由一個Lua的設計師可以免費獲得。 – ryanpattison
感謝@ rpattiso,我知道。但是,它並沒有處理我的問題AFAICT。 – 1k5