Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/lua/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何包装参数是指向结构的指针的C函数,以便可以从Lua调用它?_C_Lua_Swig - Fatal编程技术网

如何包装参数是指向结构的指针的C函数,以便可以从Lua调用它?

如何包装参数是指向结构的指针的C函数,以便可以从Lua调用它?,c,lua,swig,C,Lua,Swig,我有下面的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*,我知道如何包装它。我应该为C结构使用table类型吗 编辑:我正在使用SWIG进行包装,根据这一点,似乎我应该自动拥有此功能新建\u type\t(2,3),但事

我有下面的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*
,我知道如何包装它。我应该为C结构使用
table
类型吗

编辑:我正在使用SWIG进行包装,根据这一点,似乎我应该自动拥有此功能
新建\u type\t(2,3)
,但事实并非如此

如果包装一个C结构,它也是 映射到Lua userdata。加入 将metatable添加到userdata,如下所示 提供非常自然的界面。对于 例如

结构点{intx,y;}

其用途如下:

p=example.new\u Point()
p.x=3
p.y=5
print(p.x,p.y)35

为工会提供了类似的访问权限 以及C++类的数据成员。C 结构是使用 函数NeXyPooT(),但对于C++ 类仅使用 名称点()


我匆匆忙忙地把这个拼起来。编制,;然后我在最后一刻做了一些编辑。我希望这是接近正确的事情。浏览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
> 
#包括
#包括
const char*metaname=“mine.type\u t”;//与类型为\u t的userdata关联*
类型定义结构标记{
INTA;
int b;
}t型;
int lib_a_f_4(类型_t*t)
{
返回t->a*t->b;
}
静态整数lua_lib_a_f_4(lua_State*L){
type_t*t=luaL_checkudata(L,1,metaname);//检查参数类型
lua_数(L,(lua_数)lib_a_f_4(t));
返回1;
}
静态int lua_new_t(lua_State*L){//获取lua以分配一个初始化类型*
int a=luaL_checkint(L,1);
intb=luaL_checkint(L,2);
type_t*t=lua_newuserdata(L,sizeof(*t));
luaL_getmetatable(L,metaname);
lua_可设置元表(L,-2);
t->a=a;
t->b=b;
返回1;
}
静态常量结构luaL_reg函数[]={
{“lib_a_f_4”,lua_lib_a_f_4},
{“new_t”,lua_new_t},
{NULL,NULL}
};
int mylib_开放(lua_州*L){
luaL_寄存器(L,“mylib”,函数);
luaL_新元表(L,元名称);
卢厄波普(L,1);
返回1;
}
//在lua中编译并使用它
root@pierr-桌面:/opt/task/dt/lua/try1#gcc-shared-o mylib.so-I/usr/include/lua5.1/-llua*.c-ldl
root@pierr-桌面:/opt/task/dt/lua/try1#lua
Lua 5.1.3版权所有(C)1994-2008 Lua.org,临市局里约
>要求(“mylib”)
>t=mylib.new\u t(2,3)
>mylib.lib_a_f_4(t)
>打印(mylib.lib_a_f_4(t))
6.
> 
已解决

  • 还应在
    示例.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;
    };
    
  • 使用
    示例点()
    ,而不是
    示例点()
    (SWIG版本1.3.35)


  • 谢谢但是我应该如何在lua脚本中调用这个函数呢?您将这个函数编译到共享库
    mylib.so
    ,然后
    要求它获得一个新模块
    mylib
    。查看Lua()或免费第一版中的编程。避免使用SWIG。它造成的问题至少和它引起的问题一样多,而且手工创建API调用也很容易。@Norman:我需要包装许多遗留API,以便可以从lua调用它,所以必须采用自动方式。你还有其他建议吗?多少是“很多”?如果少于100个函数,那么最好是手工操作。但是如果你想尝试一种自动化的方法,
    tolua
    比SWIG稍微少一些疯狂。只有一点点。即使是
    tolua
    也会增加很多不必要的重量。
      example.Point()
      f=example.Point()
      f.a=2
      f.b=3
      example.lib_a_f_4(f)
      print(example.lib_a_f_4(f))