lua userdata 传值问题
2016-2-5 4:42:34
收藏:0
阅读:112
评论:1
我确信有些人可能会遇到这个问题。我有一个名为矩阵的 C++ userdata 对象,具有常规的运算符重载方式,例如。
CMatrix<T>& operator=(const CMatrix<T>& b);
CMatrix<T>& operator=(const T& rhs);
在 C++ 中,当我创建两个矩阵 A 和 B 并使 A=B 时,A 和 B 可以作为两个独立的对象使用。然而,在 Lua 中,当我写下 A=B 并改变 B 的任何属性时,A 也会改变。
显然,从 Lua 手册中可以看出,Lua 通过引用进行 userdata 赋值,这就解释了上述行为。但是,我该如何使 A=B 传递值,以便当 B 更改时 A 不受影响。
事实上,我想使赋值 A=B 传递引用,这确实非常快,Matlab 也是这样做的,但是当我第一次设置 B 的某个属性时,我希望创建独立的 B,这就是 matlab 所使用的方式,我可以从 matlab 的内存使用情况中跟踪到这一点。
如果这是可能的,是在 C++ 中还是在 lua 封装代码的某个地方完成的?任何示例代码都将非常好。
编辑1:这是我的想法,我不确定它是否会完全工作或是否足够快
typedef struct luaelement
{
int type;
std::string name;
void* addr; //新增字段
bool isRef; //新增
} luaelement;
glbLuaElementSet=new set<luaelement,comparenocaseforluaelement>();
int l_newindex(lua_State* L)
{
luaelement element;
const char* key=lua_tostring(L,-2);
string str=key;
element.name=key;
element.type=lua_type(L,-1);
// 我如何得到地址,也许是一个名为 address 的元方法
glbLuaElementSet->insert(element);
lua_rawset(L,1);
}
void l_registermetamethod(lua_State* L)
{
lua_getglobal(L,"_G");
lua_createtable(L, 0, 1);
lua_pushcfunction(L, l_newindex);
lua_setfield(L, -2, "__newindex");
lua_setmetatable(L, -2);
}
现在,借助 glbLuaElementSet 变量和 l_newindex 元方法,我可以跟踪所有插入到全局 _G 表中的变量。我计划实现并查看是否存在对已有 userdata 变量的任何引用,通过检查 void* 地址来实现。我不确定这是否真的会起作用,以及在性能方面是否值得付出努力。
点赞
评论区的留言会收到邮件通知哦~
推荐文章
- 如何将两个不同的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中获取用户配置主目录的跨平台方法
你不能。
记住:Lua 是动态类型语言。因此,虽然
A和B目前存储的是矩阵类型,但稍后写成A = 1同样是合法的,此时A存储了一个整数。C++ 和 Lua 是非常不同的语言。在 C++ 中,变量要么是对象,要么是对象的引用(指针是指针类型的对象)。每个变量只会一直保存它所起始的对象。其中存储的值可以改变,但对象本身存在,并且其生存期由相应变量的生存期定义。
在 Lua 中,变量只是对象可以存储在的盒子。该盒子与其当前所存储的对象没有任何关系,任何盒子都可以存储任何对象。并且在任何时候,你可以将该盒子中的内容与任何其他盒子中的对象进行交换。
你不能干涉将一个变量复制到另一个变量中(通常情况下如此。你可以进行元表操作,但这仅适用于该表的成员。局部变量不会受到影响)。这只是 Lua 作为一种语言的运作方式。C++ 变量是对象;Lua 变量是存储盒子。最好接受无法在 Lua 中编写 C++ 风格代码的事实,而是专注于在 Lua 中编写 Lua 风格代码。
因此,如果你想复制一个对象的副本,必须明确地创建该对象的副本。
由于多种原因,它不起作用。
首先,你正在将元表应用到全局表本身,这通常是...不礼貌的。
其次,即使你的代码可以运行,它也无法处理这种简单情况:
globalVar = {} -- 在全局表中设置一个表是完全合法的。 globalVar.value = A globalVar.value = B -- 不会触发你的复制代码。__newindex元方法是不递归的。它无法在表的层次结构中上下遍历。因此,存储在全局表中的表仍然可以更改其成员。停止试图将 Lua 变成它不是的东西。与你拥有的语言一起工作,而不是你想要的语言。