./lua/addtest.lua:9: попытка проиндексировать локальный 'testobj' (значение пользовательских данных)]]
test.exe вызвать addTest.lua и установить lua_testobj
к таблице, и addTest.lua вызвать testobj.dll, но testobj.dll не может получить "lua_testobj"
сообщение об ошибке
addTest.lua:9 попыток индексировать локальный 'testobj' (значение пользовательских данных)
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
local luapath = package.path local cpath = package.cpath print(luapath) print(cpath) local testobj= require "testobj" testobj.addTest()
и исходный код 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;
}
Я изменил 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 "(значение пользовательских данных)" неправильно.
Но я не знаю, что означает сообщение об ошибке