如何在 C++ 中从一个 Lua chunk 传递 userdata 到另一个 chunk
2018-9-9 8:24:10
收藏:0
阅读:109
评论:1
我正在尝试在 C++ 中从 Lua 脚本 (chunk A) 中获取 userdata(通过函数返回变量)并将这个 userdata 传递回 C++,以便在之后的 Lua 脚本 (chunk B) 中使用它(通过函数参数)。这样 userdata 就能像在 chunk A 中一样在 chunk B 中使用。
MyBindings.h
class Vec2
{
public:
Vec2():x(0), y(0){};
Vec2(float x, float y):x(x), y(y){};
float x, y;
};
MyBindings.i
%module my
%{
#include "MyBindings.h"
%}
%include "MyBindings.h"
main.cpp
#include <iostream>
#include <lua.hpp>
extern "C"
{
int luaopen_my(lua_State *L);
}
int main()
{
lua_State *L = luaL_newstate();
luaL_openlibs(L);
luaopen_my(L);
lua_settop(L, 0);
/* chunk A */
luaL_dostring(L, "local vec2 = my.Vec2(3, 4)\n"
"function setup()\n"
"return vec2\n"
"end\n");
/* chunk B */
luaL_dostring(L, "function test(p)\n"
"print(p.x)\n"
"end\n");
void *userDataPtr = nullptr;
/* 调用 setup 函数 */
int top = lua_gettop(L);
lua_getglobal(L, "setup");
if (lua_pcall(L, 0, LUA_MULTRET, 0))
{
std::cout << lua_tostring(L, -1) << '\n';
lua_pop(L, 1);
}
/* 检查返回值 */
if (lua_gettop(L) - top)
{
/* 将 userdata 存储到指针 */
if (lua_isuserdata(L, -1))
userDataPtr = lua_touserdata(L, -1);
}
/* 检查 userDataPtr 是否有效 */
if (userDataPtr != nullptr)
{
/* 调用 test 函数 */
lua_getglobal(L, "test");
lua_pushlightuserdata(L, userDataPtr); /* 将 userdata 作为参数传递 */
if (lua_pcall(L, 1, 0, 0))
{
std::cout << lua_tostring(L, -1) << '\n';
lua_pop(L, 1);
}
}
lua_close(L);
}
我得到的结果:
[string "local vec2 = my.Vec2(3, 4)..."]:6: attempt to index a userdata value (local 'p')
我期望的结果:
3
是否可能从 chunk A 获取 userdata 然后将其传递到 chunk B 中,使其像在 chunk A 中一样使用?
点赞
评论区的留言会收到邮件通知哦~
推荐文章
- Lua 虚拟机加密load(string.dump(function)) 后执行失败问题如何解决
- 我想创建一个 Nginx 规则,禁止访问
- 如何将两个不同的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 代码?

当你通过获取
userdata的原始指针并将其作为lightuserdata传递给参数时,你将丢失有关对象类型的所有信息。即使是lightuserdata,也没有独立的元表。正确的方法是将 Lua 值按原样传递。将原始返回值保留在 Lua 栈上,或将其复制到其他 Lua 容器(例如临时 Lua 表或 Lua 注册表)中,然后将该值在 Lua 栈上复制以将其作为参数传递。这样你就不必了解有关绑定实现的任何信息。你甚至不必在意是否是
userdata还是其他 Lua 类型。根据你的代码,这可能像这样:
#include <iostream> #include <lua.hpp> extern "C" { int luaopen_my(lua_State *L); } int main() { lua_State *L = luaL_newstate(); luaL_openlibs(L); /* 脚本块 A */ luaL_dostring(L, "local vec2 = {x=3, y=4}\n" "function setup()\n" "return vec2\n" "end\n"); /* 脚本块 B */ luaL_dostring(L, "function test(p)\n" "print(p.x)\n" "end\n"); /* 调用 setup 函数 */ int top = lua_gettop(L); lua_getglobal(L, "setup"); if (lua_pcall(L, 0, LUA_MULTRET, 0)) { std::cout << lua_tostring(L, -1) << '\n'; lua_pop(L, 1); exit(EXIT_FAILURE); // 仅为演示而失败 } /* 检查返回值 */ if (lua_gettop(L) - top) { // 栈顶现在包含从 setup() 返回的值 /* 调用 test 函数 */ lua_getglobal(L, "test"); // 将原始值作为参数传递 lua_pushvalue(L, -2); if (lua_pcall(L, 1, 0, 0)) { std::cout << lua_tostring(L, -1) << '\n'; lua_pop(L, 1); exit(EXIT_FAILURE); } // 弹出原始值 lua_pop(L, 1); }else { // 没有返回值,不需要做什么 } lua_close(L); }