将C变量链接到Lua
我正在寻找一种将C变量(整数、双精度、普通C字符串或类似)绑定到Lua的解决方案。Lua应该能够修改这个变量(在C上下文中)。我根本不想寻找一个调用C函数的解决方案(从Lua获取对该变量的引用)。我也不想为此使用任何外部库(luaapi也可以)。我已经看到,LuabRig解决了这个问题(使用这个项目:),但正如我所说,没有外部库,绝对不是C++ +/P> 使用示例: C代码将C变量链接到Lua,c,lua,C,Lua,我正在寻找一种将C变量(整数、双精度、普通C字符串或类似)绑定到Lua的解决方案。Lua应该能够修改这个变量(在C上下文中)。我根本不想寻找一个调用C函数的解决方案(从Lua获取对该变量的引用)。我也不想为此使用任何外部库(luaapi也可以)。我已经看到,LuabRig解决了这个问题(使用这个项目:),但正如我所说,没有外部库,绝对不是C++ +/P> 使用示例: C代码 typedef struct Instance { int test; /* The variable I
typedef struct Instance {
int test; /* The variable I want to link to Lua (and be able to modify it)*/
} Instance;
int main() {
lua_State* L = lua_open();
Instance instance;
instance.test = 5;
/* ... */
}
在卢阿:
instance.test = instance.test + 5
print(instance.test) -- Should be 10
回到C:
int main() {
...
printf("%i\n", instance.test); /* Should be 10 here too */
}
有解决办法吗
我并不是在寻找一个调用C函数的解决方案
你必须这么做。将始终调用C函数。即使它在Lua方面可能不明确,它也会在那里。通常,您将在Lua中的
实例对象上设置元表。它将捕获对该对象的读写操作,并通过调用C函数将这些操作重定向到C端。这是Lua/C程序员的“家庭作业”,但为了谷歌的缘故:
#include <stdio.h>
#include <stdlib.h>
#include <lauxlib.h>
#include <lualib.h>
typedef struct Instance Instance;
struct Instance {
int test1;
double test2;
};
// linstance.c {
static const char *const tname = "Instance";
enum { f_test1, f_test2 };
static const char *const fmap[] = { "test1", "test2" };
static int
l_get(lua_State *L) // (t, k) -> v
{
Instance *inst = *(Instance **)luaL_checkudata(L, 1, tname);
switch (luaL_checkoption(L, 2, NULL, fmap)) {
case f_test1: lua_pushinteger(L, inst->test1); break;
case f_test2: lua_pushnumber(L, inst->test2); break;
}
return 1;
}
static int
l_set(lua_State *L) // (t, k, v)
{
Instance *inst = *(Instance **)luaL_checkudata(L, 1, tname);
switch (luaL_checkoption(L, 2, NULL, fmap)) {
case f_test1: inst->test1 = luaL_checkinteger(L, 3); break;
case f_test2: inst->test2 = luaL_checknumber(L, 3); break;
}
return 0;
}
void
pushInstance(lua_State *L, Instance *instance)
{
Instance **ud = lua_newuserdata(L, sizeof(*ud));
*ud = instance;
if (luaL_newmetatable(L, tname)) {
lua_pushcfunction(L, l_set);
lua_setfield(L, -2, "__newindex");
lua_pushcfunction(L, l_get);
lua_setfield(L, -2, "__index");
lua_pushstring(L, tname);
lua_setfield(L, -2, "__metatable");
}
lua_setmetatable(L, -2);
}
// }
int
main(int argc, char *argv[])
{
lua_State *L = luaL_newstate();
luaL_openlibs(L);
Instance instance = { -1, -1.0 };
pushInstance(L, &instance);
lua_setglobal(L, "instance");
luaL_dostring(L, "print(instance.test1, instance.test2)");
luaL_dostring(L, "instance.test1 = 3.14; instance.test2 = 3.14");
luaL_dostring(L, "print(instance.test1, instance.test2)");
printf("%d\t%g\n", instance.test1, instance.test2);
if (luaL_dostring(L, "print(instance.UNKNOWN)")) {
printf("%s\n", lua_tostring(L, -1));
lua_pop(L, 1);
}
lua_close(L);
return 0;
}
我的意思是,我不想从Lua调用C函数来绑定变量(获取引用e.t.C)。Lua值和本机C值是独立的实体。您必须将其存储在单面上—在LuaVM中或在C中,这意味着调用func来跨VM/本机边界存储/读取值。或者,如果要将两个实体的值存储在两侧,则可以进行其他调用以同步这两个实体的值。不管是哪种方式,函数都会调用C。你能告诉我一个解决方法吗?还有,你能解释一下LuaBridge是怎么做到的吗?在LuaBridge中,您可以成功地存储对C integer的引用,并在Lua脚本中更改它,而无需调用包装函数。阅读有关Lua元表和\uuu索引
/\uu新索引
元方法的信息。这是任何桥接库的构建块。我会研究它,谢谢。如果你能改进你的答案,并举个例子,那就太好了。这非常有帮助。你的编码风格有点难理解。因此,在元表的帮助下进行索引集/获取时,会调用get函数。不知道checkudata的存在。
-1 -1
3 3.14
3 3.14
[string "print(instance.UNKNOWN)"]:1: bad argument #2 to '__index' (invalid option 'UNKNOWN')