【问题标题】:How to call a library function by its name and setting it's parameters如何通过名称调用库函数并设置其参数
【发布时间】:2017-06-12 14:37:35
【问题描述】:

我在 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: 'SetFont' 的参数 #1 错误(应为 SelSurface,已获取用户数据)

这是因为我需要提供 srf 作为 GetPosition() 函数的第一个参数...但我完全不知道该怎么做:(

我不想在调用 GetPosition() 时这样做, x,y = sub.GetPosition() 但我正在寻找一种方法来透明地将其设置在 meta 的函数中。

换句话说,我想让 HLSubSurface object 从 SubSurface 继承方法。

有什么想法吗?

谢谢。

劳伦特

【问题讨论】:

  • 明确地说,您希望调用 sub.somemethod(..) 在幕后变成 srf:somemethod(...)srf 是使用 HLSubSurface 创建时设置的任何值?
  • 完全正确 :) 我的目标是避免重复所有调用。

标签: lua lua-api


【解决方案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()

【讨论】:

  • 感谢您的回复,但我想避免重新声明我的库中的所有功能(有几十个:))。有什么方法可以将函数名作为参数传递并调用类似 obj.srf:$funcname() 的东西?
  • @destroyedlolo - 答案已更新。所有父函数都通过自动替换它们的第一个参数来继承。
  • 好的,我出去了 1 周,但是在我回来的时候,我会测试和反馈。再次感谢。
  • 如果没有编程,你将如何度过整个星期?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-02-26
  • 2021-11-12
  • 2015-12-17
  • 1970-01-01
  • 2016-05-05
  • 1970-01-01
相关资源
最近更新 更多