./lua/addtest.lua:9: попытка проиндексировать локальный ‘testobj’ (значение пользовательских данных)]]

test.exe вызвать addTest.lua и установить lua_testobj к таблице, и addTest.lua вызовите testobj.dll,
но testobj.dll не может получить «lua_testobj»

сообщение об ошибке

addTest.lua: 9 попыток индексировать локальный ‘testobj’ (значение пользовательских данных)

  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));
    
  2. следующий код addtest.lua

    local luapath = package.path
    local cpath = package.cpath
    
    print(luapath)
    print(cpath)
    
    local testobj= require "testobj"
    testobj.addTest()
    
  3. и исходный код testobj.dll следующий

    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;
    }
    

2

Решение

Это выглядит как testobj.dll действительно вернул ваш lua_testobj успешно, потому что ошибка, которую вы получаете:

addTest.lua: 9 попыток индексировать локальный ‘testobj’ (значение пользовательских данных)

указывает на Луа видит testobj как userdata, Проблема не в этом; реальная проблема заключается в том, что вы не связали метатаблицу с этими пользовательскими данными, поэтому lua не может ничего с этим поделать, когда скрипт пытается их использовать.

Я изменил ваш luaopen_testobj создать и зарегистрировать метатаблицу для вашего 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;
}

Это должно позволить вам получить доступ laddTest с помощью testobj:addTest() из Луа. laddtest следует проверить, что testobj действительно пользовательские данные, которые вы передали, например:

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

Другие решения

Я изменил luaopen_testobj функция, добавить lua_pop(L, 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) );

lua_pop(L, 1);

return 1;
}

Теперь он может правильно получить значение pTestObj, больше не появляется «addTest.lua: 9 попытка проиндексировать локальный« testobj »(значение пользовательских данных)» неправильно.

Но я не знаю, что означает сообщение об ошибке

0

По вопросам рекламы [email protected]