Lua SWIG Основы - PullRequest
       23

Lua SWIG Основы

0 голосов
/ 03 июля 2018

Я пытаюсь реализовать базовые манипуляции с векторным классом, используя инструкции, представленные по адресу:

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()

--By the way is there an equivalent in Lua?
--del v 

Я получил следующий вывод:

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

Очевидно, что модуль загружен правильно, когда я сначала печатаю адрес таблицы но я не могу создать вектор ... Я также пытался вызвать метод модуля, такой как mymodule:Vector(1,2,3), по-прежнему выдает ошибку. Что мне здесь не хватает?

Все, что я хочу, - это создать новый Vector и уничтожить его. используя метод ~ Vector3f (). Что я должен изменить, чтобы сделать этот механизм рабочий?

1 Ответ

0 голосов
/ 09 июля 2018

SWIG автоматически сгенерирует метаметод __gc из деструктора. В принципе, вашему классу даже не нужен собственный деструктор, по умолчанию он подойдет.

Кроме того, SWIG не нужно знать обо всех деталях реализации функций, подписи вполне достаточно для генерации кода оболочки. Вот почему я переместил структуру Vector3f в буквальный раздел C ++ (который также может быть в заголовочном файле) и повторил только подписи.

Вместо того, чтобы иметь функцию-член print, почему бы не добавить возможности использования Vector3f с функцией 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
...