本文介绍了./lua/addtest.lua:9:尝试索引本地"testobj"(一个userdata值)]]的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

test.exe调用addTest.lua并将 lua_testobj 设置到表中,然后addTest.lua调用testobj.dll,但是testobj.dll无法获取"lua_testobj"

test.exe call addTest.lua and set the lua_testobj to the table, and addTest.lua call testobj.dll,but testobj.dll can not get the "lua_testobj"

错误消息是

  1. test.exe

  1. test.exe

L = luaL_newstate();
// link lua lib
luaL_openlibs(L);
//
addLuaCPath( L, "./clib/?.dll" );
//
lua_pushlightuserdata(L, (void*)g_TestObj.get()); // g_TestObj is a global vars
lua_setfield(L, LUA_REGISTRYINDEX, "lua_testobj");
//
int err = 0;
err = luaL_loadfile( L, "./lua/addTest.lua" );
if( err != LUA_OK )
  printf("Failed to load addTest.lua![%s]", lua_tostring(L,-1));

err =  lua_pcall( L, 0, 1, 0 );
if( err != LUA_OK )
  printf("Failed to call addTest.lua![%s]", lua_tostring(L,-1));

  • addtest.lua代码如下

  • the addtest.lua code is following

    local luapath = package.path
    local cpath = package.cpath
    
    print(luapath)
    print(cpath)
    
    local testobj= require "testobj"
    
    testobj.addTest()
    

  • ,下面是testobj.dll源代码

  • and the testobj.dll source code is following

    static int laddTest(lua_State *L)
    {
      lua_getfield(L, LUA_REGISTRYINDEX, "lua_testobj");
      return 1;
    }
    
    extern "C" int __declspec(dllexport)
    luaopen_testobj(lua_State *L)
    {
      luaL_Reg l[] = {
        { "addTest", laddTest },
        { NULL, NULL },
      };
    
      luaL_checkversion(L);
      luaL_newlib(L,l);
    
      lua_getfield(L, LUA_REGISTRYINDEX, "lua_testobj");
      CTestObj* pTestObj = static_cast<CTestObj*>( lua_touserdata(L,-1) );
    
      return 1;
    }
    

  • 推荐答案

    看来 testobj.dll 实际上确实成功返回了 lua_testobj ,因为您得到的错误:

    It looks like testobj.dll did actually return your lua_testobj successfully because the error you're getting:

    表示lua将 testobj 视为 userdata .那不是问题所在.真正的问题是您没有将任何元表与该用户数据相关联,因此当脚本尝试使用lua时,lua不能对其进行任何操作.

    indicates lua sees testobj as a userdata. That's not where the problem is; the real issue is that you didn't associate any metatable with that userdata so lua can't really do anything with it when a script tries to use it.

    我已经修改了您的 luaopen_testobj 来为您的 testobj 创建并注册一个元表:

    I've modified your luaopen_testobj to create and register a metatable for your testobj:

    extern "C" int __declspec(dllexport)
    luaopen_testobj(lua_State *L)
    {
      luaL_Reg l[] =
      {
          { "addTest", laddTest },
          { NULL, NULL },
      };
    
      luaL_checkversion(L);
      lua_pushlightuserdata(L, (void*)g_TestObj.get());
    
      // g_TestObj, testobj_mt, {l}
      luaL_newmetatable(L, "lua_testobj");
      luaL_newlib(L, l);
      // testobj_mt.__index = {l}
      lua_setfield(L, -2, "__index");
    
      // return setmetatable(g_TestObj, testobj_mt)
      lua_setmetatable(L, -2);
      return 1;
    }
    

    这应该允许您使用lua中的 testobj:addTest()访问 laddTest . laddtest 应该检查 testobj 确实是您传入的用户数据,例如:

    This should allow you to access laddTest using testobj:addTest() from lua. laddtest should check that testobj is indeed the userdata you passed in, for example:

    static int laddTest(lua_State *L)
    {
        auto pTestObj = reinterpret_cast<CTestObj *> (luaL_checkudata(L, 1, "lua_testobj"));
        // do something ...
        return 1;
    }
    

    这篇关于./lua/addtest.lua:9:尝试索引本地"testobj"(一个userdata值)]]的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

    09-12 20:05