Как вызвать функцию библиотеки по ее имени и установить ее параметры
У меня есть библиотека функций, определенных в моем коде C:
static const struct luaL_reg SelSurfaceLib [] = {
{"CapabilityConst", CapabilityConst},
{"create", createsurface},
{NULL, NULL}
};
static const struct luaL_reg SelSurfaceM [] = {
{"Release", SurfaceRelease},
{"GetPosition", SurfaceGetPosition},
{"clone", SurfaceClone},
{"restore", SurfaceRestore},
{NULL, NULL}
};
void _include_SelSurface( lua_State *L ){
luaL_newmetatable(L, "SelSurface");
lua_pushstring(L, "__index");
lua_pushvalue(L, -2);
lua_settable(L, -3); /* metatable.__index = metatable */
luaL_register(L, NULL, SelSurfaceM);
luaL_register(L,"SelSurface", SelSurfaceLib);
}
И я могу использовать его с этим кодом Lua:
local sub = SelSurface.create()
local x,y = sub:GetPosition()
...
Теперь моя трудная проблема: я использую следующий код
function HLSubSurface(parent_surface, x,y,sx,sy )
local self = {}
-- fields
local srf = parent_surface:SubSurface( x,y, sx,sy )
-- methods
local meta = {
__index = function (t,k)
local tbl = getmetatable(srf)
return tbl[k]
end
}
setmetatable( self, meta )
return self
end
и мой основной код:
sub = HLSubSurface( parent, 0,0, 160,320 )
x,y = sub.GetPosition()
но это не удается
./HDB/80_LeftBar.lua:19: неверный аргумент №1 для 'SetFont' (ожидается SelSurface, получены данные пользователя)
Это потому, что мне нужно предоставить srf в качестве 1-го аргумента функции GetPosition()... но я строго не знаю, как это сделать:(
Я не хочу делать это при вызове GetPosition(), x,y = sub.GetPosition(), но я ищу способ сделать это прозрачно, установив его в функции meta.
Другими словами, я хотел бы иметь объект HLSubSurface для наследования методов от SubSurface.
Любая идея?
Благодарю.
Laurent
1 ответ
function HLSubSurface(parent_surface, x, y, sx, sy)
local srf = parent_surface:SubSurface(x, y, sx, sy)
local self = {
-- fields
....
}
setmetatable(self, {__index =
function (obj, key)
local parent_field
local parent_fields = getmetatable(srf).__index
if type(parent_fields) == "function" then
parent_field = parent_fields(key)
elseif parent_fields then
parent_field = parent_fields[key]
end
if type(parent_field) == "function" then
return
function(o, ...)
if o == obj then
return parent_field(srf, ...)
else
return parent_field(o, ...)
end
end
else
return parent_field
end
end
})
return self
end
И ваш основной код будет:
sub = HLSubSurface( parent, 0,0, 160,320 )
x,y = sub:GetPosition()