我有以下C功能。我应该如何包装它以便可以从Lua脚本中调用它?
typedef struct tagT{
int a ;
int b ;
} type_t;
int lib_a_f_4(type_t *t)
{
return t->a * t->b ;
}
如果函数参数类型为int
或char *
,我知道如何进行包装。我应该将table
类型用于C结构吗?
编辑:根据这个doc,我正在使用SWIG进行包装,似乎我应该自动拥有这个函数new_type_t(2,3)
,但事实并非如此。
如果你包装一个C结构,它也是 映射到Lua用户数据。通过添加一个 metatable到userdata,这个 提供了非常自然的界面。对于 例如,
struct Point{ int x,y; };
使用如下:
p=example.new_Point()
p.x=3
p.y=5
print(p.x,p.y) 3 5
为工会提供类似的访问权限 和C ++类的数据成员。 C 使用a创建结构 函数new_Point(),但是对于C ++ 只使用。创建类 名称Point()。
答案 0 :(得分:2)
我把它们放在一起很匆忙。它汇编;然后我做了一些最后一分钟的编辑。我希望它接近正确的事情。浏览Lua手册,查看所有不熟悉的功能。
#include <lua.h>
#include <lauxlib.h>
const char *metaname = "mine.type_t"; // associated with userdata of type type_t*
typedef struct tagT{
int a ;
int b ;
}type_t;
int lib_a_f_4(type_t *t)
{
return t->a * t->b ;
}
static int lua_lib_a_f_4(lua_State *L) {
type_t *t = luaL_checkudata(L, 1, metaname); // check argument type
lua_pushnumber(L, (lua_Number)lib_a_f_4(t));
return 1;
}
static int lua_new_t(lua_State *L) { // get Lua to allocate an initialize a type_t*
int a = luaL_checkint(L, 1);
int b = luaL_checkint(L, 2);
type_t *t = lua_newuserdata(L, sizeof(*t));
luaL_getmetatable(L, metaname);
lua_setmetatable(L, -2);
t->a = a;
t->b = b;
return 1;
}
static const struct luaL_reg functions[] = {
{ "lib_a_f_4", lua_lib_a_f_4 },
{ "new_t", lua_new_t },
{ NULL, NULL }
};
int mylib_open(lua_State *L) {
luaL_register(L, "mylib", functions);
luaL_newmetatable(L, metaname);
lua_pop(L, 1);
return 1;
}
//compile and use it in lua
root@pierr-desktop:/opt/task/dt/lua/try1# gcc -shared -o mylib.so -I/usr/include/lua5.1/ -llua *.c -ldl
root@pierr-desktop:/opt/task/dt/lua/try1# lua
Lua 5.1.3 Copyright (C) 1994-2008 Lua.org, PUC-Rio
> require("mylib")
> t=mylib.new_t(2,3)
> mylib.lib_a_f_4(t)
> print(mylib.lib_a_f_4(t))
6
>
答案 1 :(得分:0)
解决。
还应在example.i
文件中添加类型定义,仅包含.h
是不够的。
%module example
%{
#include "liba.h"
%}
void lib_a_f_1(void);
int lib_a_f_2(int a, int b);
int lib_a_f_3(const char *s);
int lib_a_f_4(struct Point *t);
struct Point{
int a;
int b;
};
使用example.Point()
,而不是example.new_Point()
(SWIG版本1.3.35)
example.Point()
f=example.Point()
f.a=2
f.b=3
example.lib_a_f_4(f)
print(example.lib_a_f_4(f))