加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

如何将C对象返回到lua 5.2?

发布时间:2020-12-16 07:34:54 所属栏目:百科 来源:网络整理
导读:如何将C对象返回到lua? 我的C代码如下: class MyClass{public: void say() { print("Hellorn"); }};int test(lua_State* l){ MyClass* obj = new MyClass(); lua_pushlightuserdata(l,obj); return 1;} Lua测试如下: local a = MyClass:new()a:say() --
如何将C对象返回到lua?

我的C代码如下:

class MyClass
{
public:
  void say()
  {
    print("Hellorn");
  }
};

int test(lua_State* l)
{
  MyClass* obj = new MyClass();
  lua_pushlightuserdata(l,obj);
  return 1;
}

Lua测试如下:

local a = MyClass:new()
a:say()  <--- OK,beacause I set metatable!!
local b = test()
b:say()  <--- ERROR: attempt to index local 'b' (a userdata value)

如何修改test()函数才能正常工作?
obj将由lua自动毁灭?

PS:我已经设置了MyClass metatable如下

void l_registerClass()
{
  lua_newtable(l);
  int methods = lua_gettop(l);
  luaL_newmetatable(l,"MyClass");
  int metatable = lua_gettop(l);
  lua_pushvalue(l,methods);
  lua_setglobal(l,"MyClass");

  lua_pushvalue(l,methods);  
  l_set(l,metatable,"__metatable");

  //set metatable __index
  lua_pushvalue(l,methods);
  l_set(l,"__index");

  //set metatable __gc
  lua_pushcfunction(l,l_destructor);  
  l_set(l,"__gc");

  //set method table
  lua_newtable(l);                // mt for method table  
  lua_pushcfunction(l,l_constructor);  
  lua_pushvalue(l,-1);           // dup new_T function  
  l_set(l,methods,"new");         // add new_T to method table  
  l_set(l,-3,"__call");           // mt.__call = new_T  
  lua_setmetatable(l,methods);  

  // set methods metatable   
  lua_pushstring(l,"say");
  lua_pushcclosure(l,l_proxy,1);  
  lua_settable(l,methods);

  lua_pop(l,2);
}

int l_proxy(lua_State* l)
{
  int i = (int)lua_tonumber(l,lua_upvalueindex(1));
  lua_remove(l,1);  // remove self so member function args start at index 1
  //call real function
  MyClass* obj = getInstance();
  obj->say();
  return 1;
}

我不应该失去一步吗?
我没有使用任何Lua绑定框架,我使用的是纯Lua库.

====更新1 ====

感谢user1520427的回答,但….

int test(lua_State* l)
{
  MyClass** c = (MyClass**)lua_newuserdata(l,sizeof(MyClass*));
  *c = new MyClass();       // we manage this
  lua_getglobal(l,"MyClass");
  lua_setmetatable(l,-2);
  return 1;
}

我在Lua测试它

local b = test()
print( type(b) )
local meta = getmetatable(b)
for k,v in pairs(meta) do
  print("    ",k,v)
end

Lua show metatable是正确的.

userdata
  say     function: 00602860
  new     function: 00493665

但是lua仍然显示相同的错误

b:say()   <-- attempt to index local 'b' (a userdata value)

===更新2 ===

int test(lua_State* l)
{
  MyClass** c = (MyClass**)lua_newuserdata(l,sizeof(MyClass*));
  *c = new MyClass();       // we manage this
  luaL_getmetatable(l,"MyClass");  //
  lua_getglobal(l,-2);
  return 1;
}

lua测试结果:

b:say()   <-- attempt to call method 'say' (a nil value)

===更新3 ===

int test(lua_State* l)
{
  MyClass** c = (MyClass**)lua_newuserdata(l,"MyClass");  
  luaL_setmetatable(l,"MyClass");  //modify
  return 1;
}

Lua测试结果:

b:say()   <-- calling 'say' on bad self

解决方法

您没有将您从测试中返回的内容与您注册的课程相关联.尝试类似的东西:

int test(lua_state* l) { 
  MyClass** c = lua_newuserdata(l,sizeof(MyClass*)); // lua will manage the MyClass** ptr
    *c = new MyClass(); // we manage this
    luaL_getmetatable(l,"MyClass");
    lua_setmetatable(l,-2);
    return 1;
}

这是我的头脑,但你明白了.你已经设置了析构函数,所以当Lua垃圾收集用户数据时,它会调用你的__gc函数,然后应该强制转换,取消引用和删除数据.

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读