【问题标题】:SWIG Lua: Extending (%extend) class with %native. Is it possible to add %native method?SWIG Lua:使用 %native 扩展 (%extend) 类。是否可以添加 %native 方法?
【发布时间】:2014-01-25 08:50:25
【问题描述】:
%module test
class Foo{
public:
  Foo(); 
}

我想要这样的东西:

%extend Foo{
%native(Bar) int Bar(lua_State * L);
}

【问题讨论】:

    标签: c++ lua swig


    【解决方案1】:

    在绑定的 .i 文件中,最后包含以下代码:

    %wrapper %{
    // This is code to add a new function to the object's metatable
    void script_addNativeMethod(lua_State *L, const char *className, const char *methodName, lua_CFunction fn)
    {
        SWIG_Lua_get_class_registry(L); /* get the registry */
        lua_pushstring(L, className);   /* get the name */
        lua_rawget(L,-2);               /* get the metatable itself */
        lua_remove(L,-2);               /* tidy up (remove registry) */
    
        // If the metatable is not null, add the method to the ".fn" table
        if(lua_isnil(L, -1) != 1)
        {
            SWIG_Lua_get_table(L, ".fn");
            SWIG_Lua_add_function(L, methodName, fn);
            lua_pop(L, 2);              /* tidy up (remove metatable and ".fn" table) */
        }
        else
        {
            printf("[script_addNativeMethod(..)] - \"%s\" metatable is not found. Method \"%s\" will not be added\n", className, methodName);
            return;
        }
    }
    %}
    

    这样做是在包装 CPP 文件中添加一个名为“script_addNativeMethod”的新函数。您可以像这样在“init”绑定代码中调用此函数:

    // Wrapper to add native Lua methods to existing C++ classes
    %init %{
        script_addNativeMethod(L, "MetatableName", "methodName", /*int function(lua_State *L)*/function);
    %}
    

    最重要的是,在绑定文件中,您需要有实际的本地 lua 函数,您想将其用作用户数据的方法:

    %{
    int function(lua_State *L)
    {
        printf("Method called!\n");
        return 0;
    }
    %}
    

    我几乎只是想通了这一点,我想在这里发布它,因为这个页面在谷歌中排名很高,这是完成工作的一个相当不错的解决方案。这需要在您使用 SWIG 编写的每个包装绑定 (*.i) 文件中完成。

    祝你好运!

    【讨论】:

      【解决方案2】:

      Lua 没有任何真正的方法概念,只有带有一些语法糖的函数表,因此您可以编写看起来非常 OO'ish 的 Lua 代码:

      foo = test.Foo() # will call the C++ Foo constructor and return a wrapped (Lua) Foo
      myInt = foo:Bar()
      

      当你写作时

      myInt = foo:Bar()
      

      Lua 实际上正在执行

      myInt = foo.Bar(foo)
      

      这将导致 Lua 在 foo 元表中查找名为 Bar 的函数,并将 foo 实例作为第一个参数。因此,您需要做的更多的是遵循以下伪代码(未经测试,可能存在语法错误,参数顺序错误等,但希望您能理解):

      %native(Bar) int Bar(lua_State * L);
      
      %{
      int Bar(lua_State*L) {
        // there should be one arg on the stack: the Foo instance
        Foo* foo = (Foo*)<get void* from L stack>
        int answer = foo.Bar();
        // push answer onto L stack
        lua_pushnumber(L, answer);
        return 1;
      }
      %}
      
      %luacode {
        test.Foo.Bar = test.Bar
      }
      ...
      %}
      

      %luacode 使 Bar 作为 Foo“类”的一部分可用,尽管我在该领域有点生疏,您可能必须添加 Bar Foo 元表,或者从 C 中执行(参见第 5.6 节.i 文件部分的 SWIG 用户指南,您可以在其中尝试执行此操作)。

      很想知道这是否有效。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2018-10-15
        • 2011-05-07
        • 2015-06-11
        • 1970-01-01
        • 2014-10-05
        • 1970-01-01
        • 2016-07-01
        相关资源
        最近更新 更多