Lua SWIG 基础

我正在尝试使用以下网址提供的指令实现基本的向量类操作:

http://swig.org/Doc1.3/SWIG.html#SWIG_adding_member_functions

我有下面的.i文件:

%module mymodule
%{
    typedef struct
    {
        float x,y,z;
    } Vector3f;
%}

typedef struct
{
    float x,y,z;
} Vector3f;

%extend Vector3f {
    Vector3f(float x, float y, float z) {
    Vector3f *v;
    v = (Vector3f *) malloc(sizeof(Vector3f));
    v->x = x;
    v->y = y;
    v->z = z;
    return v;
}
~Vector3f() {
    free($self);
}
void print() {
    printf("Vector [%f, %f, %f]\n", $self->x,$self->y,$self->z);
}
};

现在我的问题是,如果在 Lua 中调用以下代码:

print(mymodule)
local v = Vector(3,4,0)
v.print()

--顺便问一下,在 Lua 中有相当的东西吗?
--del v

我有如下输出:

table: 0x000001F9356B1920
attempt to call global 'Vector' (a nil value)

很明显模块已经正确加载,因为我首先打印了表地址 但我无法创建一个向量... 我还尝试调用模块方法 mymodule:Vector(1,2,3) 仍然会生成一个错误。我错过了什么?

我想要的就是生成一个新的 Vector,并使用 ~Vector3f() 方法销毁它的 GC。我应该修改什么来使这个机制 工作?

点赞
用户1944004
用户1944004

SWIG 会从析构函数自动生成一个 __gc 元方法。原则上,您的类甚至不需要自定义析构函数,缺省的也能正常工作。

此外,SWIG 并不需要知道函数的所有实现细节,只需要函数签名即可生成包装器代码。这就是为什么我将 Vector3f 结构体移动到了字面量的 C++ 部分(也可以在头文件中),并只重复了函数签名。

为了代替 print 成员函数,为什么不增加能够与 Lua 的 print() 函数一起使用的能力呢?只需要编写一个 __tostring 函数返回对象的字符串表示即可。

test.i

%module mymodule
%{
#include <iostream>

struct Vector3f {
    float x,y,z;
    Vector3f(float x, float y, float z) : x(x), y(y), z(z) {
        std::cout << "Constructing vector\n";
    }
    ~Vector3f() {
        std::cout << "Destroying vector\n";
    }
};
%}

%include <std_string.i>

struct Vector3f
{
    Vector3f(float x, float y, float z);
    ~Vector3f();
};

%extend Vector3f {
    std::string __tostring() {
        return std::string{"Vector ["}
            + std::to_string($self->x) + ", "
            + std::to_string($self->y) + ", "
            + std::to_string($self->z) + "]";
    }
};

test.lua

local mymodule = require("mymodule")
local v = mymodule.Vector3f(3,4,0)
print(v)

编译和运行的示例工作流程:

$ swig -lua -c++ test.i
$ clang++ -Wall -Wextra -Wpedantic -I/usr/include/lua5.2/ -fPIC -shared test_wrap.cxx -o mymodule.so -llua5.2
$ lua test.lua
Constructing vector
Vector [3.000000, 4.000000, 0.000000]
Destroying vector
2018-07-08 23:24:22