Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/160.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函数返回自定义数据_C++_C_Lua_Luabind - Fatal编程技术网

C++ Lua从C函数返回自定义数据

C++ Lua从C函数返回自定义数据,c++,c,lua,luabind,C++,C,Lua,Luabind,尽管搜索很困难,但我找不到一个有效的LuaC API示例,用于调用从C函数返回自定义数据的Lua函数。 例如,我有一个注册函数“GetMyVector”,然后我从lua调用它来从C检索信息,我得到的是一个表,但我想要的是类似于从C中的结构访问access变量的东西,例如: local x = GetMyVector() print(x[1]) -- i print(x[2]) -- j print(x[3]) -- k -- how to access it via like this: pr

尽管搜索很困难,但我找不到一个有效的LuaC API示例,用于调用从C函数返回自定义数据的Lua函数。 例如,我有一个注册函数“GetMyVector”,然后我从lua调用它来从C检索信息,我得到的是一个表,但我想要的是类似于从C中的结构访问access变量的东西,例如:

local x = GetMyVector()
print(x[1]) -- i 
print(x[2]) -- j
print(x[3]) -- k
-- how to access it via like this:
print(x.i)
print(x.j)
print(x.k)
my C函数通过lua_pushnumber在三维数组中推送向量:

static int GetMyVector(lua_State *L)
{
    vec3_t vec;
    vec[0] = 1;
    vec[1] = 2;
    vec[3] = 3;
    lua_newtable(L);
    lua_pushnumber(L, vec[0]);
    lua_rawseti(L, -2, 1);
    lua_pushnumber(L, vec[1]);
    lua_rawseti(L, -2, 2);
    lua_pushnumber(L, vec[2]);
    lua_rawseti(L, -2, 3);
    return 1;
}
你可能想要。它允许为表格设置任何键。如果键是文本,则可以通过
x[“i”]
x.i
获取数据。 代码应该类似于

static int GetMyVector(lua_State *L)
{
    vec3_t vec;
    vec[0] = 1;
    vec[1] = 2;
    vec[3] = 3;
    lua_newtable(L);

    lua_pushliteral(L, "i");
    lua_pushnumber(L, vec[0]);
    lua_settable(L, -2);

    lua_pushliteral(L, "j");
    lua_pushnumber(L, vec[1]);
    lua_settable(L, -2);

    lua_pushliteral(L, "k");
    lua_pushnumber(L, vec[2]);
    lua_settable(L, -2);
    return 1;
}

它有一点扩展,但由于@geov,我找到了我想要的东西,它有点类似于C#中的属性样式。我想,解决方案如下:

#define MYCLASSNAME "vec"

typedef struct {
    int i, j, k;
} MyVec_t;

typedef int(*Xet_func) (lua_State *L, void *v);

/* member info for get and set handlers */
typedef const struct{
    const char *name;  /* member name */
    Xet_func func;     /* get or set function for type of member */
    size_t offset;     /* offset of member within MyVec_t */
}  Xet_reg_pre;

typedef Xet_reg_pre * Xet_reg;

// properties
static int Get_Int(lua_State *L, void *v) {
    lua_pushnumber(L, *(int*)v);
    return 1;
}

static int Set_Int(lua_State *L, void *v) {
    *(int*)v = luaL_checkinteger(L, 3);
    return 0;
}

static int Get_Number(lua_State *L, void *v) {
    lua_pushnumber(L, *(lua_Number*)v);
    return 1;
}

static int Set_Number(lua_State *L, void *v) {
    *(lua_Number*)v = luaL_checknumber(L, 3);
    return 0;
}

static int Get_String(lua_State *L, void *v) {
    lua_pushstring(L, (char*)v);
    return 1;
}

static void Property_Add(lua_State *L, Xet_reg l)
{
    for (; l->name; l++) {
        lua_pushstring(L, l->name);
        lua_pushlightuserdata(L, (void*)l);
        lua_settable(L, -3);
    }
}

static int Property_Call(lua_State *L)
{
    Xet_reg m = (Xet_reg)lua_touserdata(L, -1);  
    lua_pop(L, 1);                               
    luaL_checktype(L, 1, LUA_TUSERDATA);
    return m->func(L, (void *)((char *)lua_touserdata(L, 1) + m->offset));
}

static int index_handler(lua_State *L)
{
    /* stack has userdata, index */
    lua_pushvalue(L, 2);                     /* dup index */
    lua_rawget(L, lua_upvalueindex(1));      /* lookup member by name */
    if (!lua_islightuserdata(L, -1)) {
        lua_pop(L, 1);                         /* drop value */
        lua_pushvalue(L, 2);                   /* dup index */
        lua_gettable(L, lua_upvalueindex(2));  /* else try methods */
        if (lua_isnil(L, -1))                  /* invalid member */
            luaL_error(L, "cannot get member '%s'", lua_tostring(L, 2));
        return 1;
    }
    return Property_Call(L);                      /* call get function */
}

static int newindex_handler(lua_State *L)
{
    /* stack has userdata, index, value */
    lua_pushvalue(L, 2);                     /* dup index */
    lua_rawget(L, lua_upvalueindex(1));      /* lookup member by name */
    if (!lua_islightuserdata(L, -1))         /* invalid member */
        luaL_error(L, "cannot set member '%s'", lua_tostring(L, 2));
    return Property_Call(L);                      /* call set function */
}

static MyVec_t *CheckMyVec(lua_State *L, int index) // get data
{
    MyVec_t *p;
    luaL_checktype(L, index, LUA_TUSERDATA);
    p = (MyVec_t *)luaL_checkudata(L, index, MYCLASSNAME);
    return p;
}

static MyVec_t *PushMyVec(lua_State *L) // push data
{
    MyVec_t *p = (MyVec_t *)lua_newuserdata(L, sizeof(MyVec_t));
    luaL_getmetatable(L, MYCLASSNAME);
    lua_setmetatable(L, -2);
    return p;
}

static int MyVec_Create(lua_State *L)   // C function which will push data
{
    MyVec_t *p;
    p = PushMyVec(L);
    p->i = luaL_checkinteger(L, 1);
    p->j = luaL_checkinteger(L, 2);;
    p->k = luaL_checkinteger(L, 3);;
    return 1;
}

static int MyVec_destroy(lua_State *L)
{
    MyVec_t *p = (MyVec_t *)lua_touserdata(L, 1);
    return 0;
}

static int MyVec_Position(lua_State *L)
{
    MyVec_t *p = CheckMyVec(L, 1);
    double   x = p->i;
    double   y = p->j;
    double   z = p->k;
    if (lua_gettop(L) > 1) {
        p->i = luaL_checknumber(L, 2);
        p->j = luaL_checknumber(L, 3);
        p->k = luaL_checknumber(L, 4);
    }
    lua_pushnumber(L, x);
    lua_pushnumber(L, y);
    lua_pushnumber(L, z);
    return 2;
}


static const luaL_Reg myvec_meta_methods[] = {
    { "__gc", MyVec_destroy },
    { 0, 0 }
};

static const luaL_Reg myvec_methods[] = {
    { "create",  MyVec_Create },
    { "position", MyVec_Position },
    { 0, 0 }
};

static const Xet_reg_pre MyVec_get[] = {
    { "i", Get_Int, offsetof(MyVec_t, i) },
    { "j", Get_Int, offsetof(MyVec_t, j) },
    { "k", Get_Int, offsetof(MyVec_t, k) },
    { 0, 0 }
};

static const Xet_reg_pre MyVec_set[] = {
    { "i", Set_Int, offsetof(MyVec_t, i) },
    { "j", Set_Int, offsetof(MyVec_t, j) },
    { "k", Set_Int, offsetof(MyVec_t, k) },
    { 0, 0 }
};


int MyVec_Register(lua_State *L)
{
    int metatable, methods;

    /* create methods table, & add it to the table of globals */
    luaL_openlib(L, MYCLASSNAME, myvec_methods, 0);
    methods = lua_gettop(L);

    /* create metatable for MyVec_t, & add it to the registry */
    luaL_newmetatable(L, MYCLASSNAME);
    luaL_openlib(L, 0, myvec_meta_methods, 0);  /* fill metatable */
    metatable = lua_gettop(L);

    lua_pushliteral(L, "__metatable");
    lua_pushvalue(L, methods);              /* dup methods table*/
    lua_rawset(L, metatable);               /* hide metatable:
                                            metatable.__metatable = methods */
    lua_pushliteral(L, "__index");
    lua_pushvalue(L, metatable);            /* upvalue index 1 */
    Property_Add(L, MyVec_get);             /* fill metatable with getters */
    lua_pushvalue(L, methods);              /* upvalue index 2 */
    lua_pushcclosure(L, index_handler, 2);
    lua_rawset(L, metatable);               /* metatable.__index = index_handler */

    lua_pushliteral(L, "__newindex");
    lua_newtable(L);                        /* table for members you can set */
    Property_Add(L, MyVec_set);             /* fill with setters */
    lua_pushcclosure(L, newindex_handler, 1);
    lua_rawset(L, metatable);               /* metatable.__newindex = newindex_handler */

    lua_pop(L, 1);                          /* drop metatable */
    return 1;                               /* return methods on the stack */
}

“如果您有任何关于这方面的教程和信息,请将lnk粘贴到下面,我将不胜感激。”要求我们推荐或查找书籍、工具、软件库、教程或其他非现场资源的问题因堆栈溢出而脱离主题,因为它们往往会吸引固执己见的答案和垃圾邮件。相反,请描述问题以及迄今为止为解决问题所做的工作。是的,我设法解决了这个问题,但老实说,我不知道该怎么做,因为我也不知道该如何命名,也找不到任何关于这方面的信息来采取一点措施并解决这个问题。