How to wrap a C function whose parameters are pointer to structs, so that it can be called from Lua?
I have the follwing C function. How should I wrap it so it can be called from a Lua script?
typedef struct tagT{
int a ;
int b ;
} type_t;
int lib_a_f_4(type_t *t)
{
return t->a * t->b ;
}
I know how to wrapr it if the function parameter type were int
or char *
. Should I use table
type for a C structure?
EDIT: I am using SWIG for the wraping , according to this doc, It seems that I should automatically have this function new_type_t(2,3)
, but it is not the case.
If you wrap a C structure, it is also mapped to a Lua userdata. By adding a metatable to the userdata, this provides a very natural interface. For 开发者_如何学JAVA example,
struct Point{ int x,y; };
is used as follows:
p=example.new_Point()
p.x=3
p.y=5
print(p.x,p.y) 3 5
Similar access is provided for unions and the data members of C++ classes. C structures are created using a function new_Point(), but for C++ classes are created using just the name Point().
I put this together in a hurry. It compiled; then I did a few last-minute edits. I hope it's close to the right thing. Go through the Lua manual and look at all the unfamiliar functions.
#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
>
Solved.
Should also add the type definition in the
example.i
file , just include the.h
is not enough.%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; };
use
example.Point()
,notexample.new_Point()
(SWIG Version 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))
精彩评论