将C语言中的整数绑定到Lua全局变量。
2017-3-13 5:42:40
收藏:0
阅读:74
评论:2
在 C 语言中,我想要调用一个 Lua 函数 myFunction(),该函数使用了一个全局变量 x。我想直接将 C 语言中的一个整数变量注册为这个全局变量 x。
大概是这样:
demo.lua:
function myFunction()
return x + 3
end
demo.c:
int x = 0;
lua_bindglob(L, "x", &x);
for (x = 0; x < 100; ++x)
{
lua_getglobal(L, "myFunction");
// 在这里调用函数,它应该会求出 x 的当前值(在 C 语言中)
lua_pcall(L, 0, 1, 0);
int result = lua_tonumber(L, -1);
lua_pop(L, 1);
}
我知道我可以通过以下方式修改 Lua 中的全局变量:
lua_pushnumber(L, 3);
lua_setglobal(L, "x");
但我需要有一种更直接/更快的方法来实现这一点。我得到了一个提示,说 LUA ligthuserdata 可能会对此有所帮助,但我找不到任何关于普通变量的示例。
编辑: 由于我从基准测试中获取表达式,所以我不想改变它们: 见这里的示例:
点赞
用户3677376
如果您只有一些从 Lua 访问的 C 变量,您可以在全局表上设置一个具有 __index 和 __newindex 元方法的元表。当访问(get 或 set)不存在的全局变量时,这些元方法被调用,您需要查看这些元方法的第二个参数(变量名)来确定该怎么做。
导出单个变量的模块的示例代码:
#include <string.h>
#include <limits.h>
#include <lua.h>
#include <lauxlib.h>
static int x = 0;
static int myvar_index(lua_State* L) {
char const* key = lua_tostring(L, 2);
if (key != NULL && strcmp(key, "x") == 0)
lua_pushinteger(L, x);
else
lua_pushnil(L);
return 1;
}
static int myvar_newindex(lua_State* L) {
char const* key = lua_tostring(L, 2);
if (key != NULL && strcmp(key, "x") == 0) {
lua_Integer i = luaL_checkinteger(L, 3);
if (i > INT_MAX || i < INT_MIN)
luaL_error(L, "variable value out of range");
x = i;
} else
lua_rawset(L, 1);
return 0;
}
int luaopen_myvar(lua_State* L) {
luaL_Reg const metamethods[] = {
{ "__index", myvar_index },
{ "__newindex", myvar_newindex },
{ NULL, NULL }
};
#if LUA_VERSION_NUM < 502
lua_pushvalue(L, LUA_GLOBALSINDEX);
lua_newtable(L);
luaL_register(L, NULL, metamethods);
#else
lua_pushglobaltable(L);
luaL_newlib(L, metamethods);
#endif
lua_setmetatable(L, -2);
return 0;
}
您要导出的 C 变量越多,元方法实现就越复杂,最好使用其他建议的方法。
还要注意,全局表是一个共享资源,所以您必须避免/处理与其他修改其元表的代码发生冲突。 (即可重用的模块不应修改共享资源-但我想同样适用于 C 中的全局变量...)
2016-01-13 17:06:27
评论区的留言会收到邮件通知哦~
推荐文章
- 如何将两个不同的lua文件合成一个 东西有点长 大佬请耐心看完 我是小白研究几天了都没搞定
- 如何在roblox studio中1:1导入真实世界的地形?
- 求解,lua_resume的第二次调用继续执行协程问题。
- 【上海普陀区】内向猫网络招募【Skynet游戏框架Lua后端程序员】
- SF爱好求教:如何用lua实现游戏内调用数据库函数实现账号密码注册?
- Lua实现网站后台开发
- LUA错误显式返回,社区常见的规约是怎么样的
- lua5.3下载库失败
- 请问如何实现文本框内容和某个网页搜索框内容连接,并把网页输出来的结果反馈到另外一个文本框上
- lua lanes多线程使用
- 一个kv数据库
- openresty 有没有比较轻量的 docker 镜像
- 想问一下,有大佬用过luacurl吗
- 在Lua执行过程中使用Load函数出现问题
- 为什么 neovim 里没有显示一些特殊字符?
- Lua比较两个表的值(不考虑键的顺序)
- 有个lua简单的项目,外包,有意者加微信 liuheng600456详谈,最好在成都
- 如何在 Visual Studio 2022 中运行 Lua 代码?
- addEventListener 返回 nil Lua
- Lua中获取用户配置主目录的跨平台方法
最好的方法就是创建一个
__call元方法,通过这个方法可以创建一个拥有正常 userdata(非轻量级)的函数,用于获取/设置 C 值。所以你的函数如下所示:
function myFunction() return x() + 3 end你可以定义操作元方法,使得像
x + 3这样的操作能够正常工作,但是没有办法让一个裸的x表达式返回你想要的值。要设置值,可以这么做:
不能像
x = 3那样使用,因为这会始终覆盖已有的值。使用
__newindex和__index元方法也不行,因为你希望这个变量是_全局_的。或者,你可以使用 LuaJIT 和其 FFI 接口。