Lua SWIG 基础知识
Lua SWIG Basics
我正在尝试使用以下位置提供的说明实现基本矢量 class 操作:
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)
显然,当我第一次打印 table 地址时,模块已正确加载
但我无法创建 Vector...我也尝试调用 mymodule:Vector(1,2,3)
之类的模块方法仍然会产生错误。我在这里错过了什么?
我只想生成一个新的 Vector
并让 GC 销毁它
使用 ~Vector3f() 方法。我应该修改什么来使这个机制
工作?
SWIG 将从析构函数中自动生成一个 __gc
元方法。原则上,您的 class 甚至不需要自定义析构函数,默认析构函数就可以了。
此外,SWIG 不需要了解函数的所有实现细节,签名完全足以生成包装代码。这就是为什么我将 Vector3f
结构移动到文字 C++ 部分(也可以在头文件中)并且只重复签名的原因。
与其拥有 print
成员函数,为什么不添加将 Vector3f
与 Lua 的 print()
函数一起使用的功能?只需编写一个 __tostring
函数,其中 returns 对象的字符串表示形式。
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
我正在尝试使用以下位置提供的说明实现基本矢量 class 操作:
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)
显然,当我第一次打印 table 地址时,模块已正确加载
但我无法创建 Vector...我也尝试调用 mymodule:Vector(1,2,3)
之类的模块方法仍然会产生错误。我在这里错过了什么?
我只想生成一个新的 Vector
并让 GC 销毁它
使用 ~Vector3f() 方法。我应该修改什么来使这个机制
工作?
SWIG 将从析构函数中自动生成一个 __gc
元方法。原则上,您的 class 甚至不需要自定义析构函数,默认析构函数就可以了。
此外,SWIG 不需要了解函数的所有实现细节,签名完全足以生成包装代码。这就是为什么我将 Vector3f
结构移动到文字 C++ 部分(也可以在头文件中)并且只重复签名的原因。
与其拥有 print
成员函数,为什么不添加将 Vector3f
与 Lua 的 print()
函数一起使用的功能?只需编写一个 __tostring
函数,其中 returns 对象的字符串表示形式。
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