2017-11-21 3 views
3

Ich habe den folgenden einfachen Code in C++, wo Objekt ist ein std Behälter:C++/Lua FFI Userdata als Tabelle zu rendern?

static int create_an_object(lua_State* L) { 
    auto obj = static_cast<Object*>(lua_newuserdata(L, sizeof(Object*))); 
    *obj = another_valid_obj; 

    luaL_newmetatable(L, "object_metatable"); 
    lua_pushcfunction(L, object_metatable_function); 
    lua_setfield(L, -2, "__index"); 
    lua_pop(L, 1); 
    return 1; 
} 

static int object_metatable_function(lua_State* L) { 
    string index = luaL_checkstring(L, -1); 
    if (index == "foo") { 
    lua_pushnumber(L, 123); 
    } 
    // Handles other indices, or throws error. 
} 

lua_pushcfunction(L, create_an_object); 
lua_setglobal(L, "create_an_object"); 

Mit dem FFI oben, ich Indizierung von Object in Lua wie erreichen kann:

local obj = create_an_object() 
print(obj.foo) -- 123 

Inzwischen print(obj) Shows Dieses Objekt ist userdata: 0x12345678.

Ist es möglich, etwas Metamethod Magie zu verwenden, so dass obj als Tabelle verwendet werden konnte, während print(obj.foo) 123 noch druckt? Ich führe meinen Code in Lua 5.1.

Antwort

0

Ich bin nicht genau sicher, was Sie mit "könnte als Tabelle verwendet werden", aber wenn Sie etwas anderes als die Standardausgabe von print(obj) drucken möchten, dann müssen Sie __tostring metamethod zuweisen und eine Zeichenfolge aus zurückgeben es. Diese Zeichenfolge kann wie folgt aussehen: "userdata: 0x12345678 = {foo = 123}", wenn Sie möchten (oder einfach "{foo = 123}").

Wenn Sie meinen, es als Tabelle arbeiten zu lassen, wenn Sie ihm einen neuen Index zuweisen, sollte __newindex metamethod verwendet werden.

+0

Ich möchte Operationen einschließlich Index, iPair/Paar Iteration und Getlen (#) für diese Benutzerdaten unterstützen. – TangKe

+0

Sie können '__pairs' /' __ipairs' Metamethoden (Lua 5.2+) und ['__len' Metamethod] (https://www.lua.org/manual/5.2/manual.html#3.4.6) verwenden, um dies zu erreichen . –

+0

Ja, ich weiß, dass es in 5.2+ machbar ist, aber ich kann nur 5.1 verwenden :( – TangKe