Mam klasy w C++ o nazwie „Punkt”:Jak wyodrębnić wskaźnik C++ obiektu od Lua
class Point
{
public:
int x, y;
//constructor
Point(int x, int y)
{
this->x = x;
this->y = y;
}
};
Moim celem jest, aby móc instancję obiektu Point ze skryptu Lua, i wyodrębnić wskaźnik ten obiekt ze stosu Lua.
Oto moja (obecnie nie działa) próba, która, mam nadzieję, wyjaśnia, co dokładnie próbuję zrobić; pamiętać, że ten kod jest zasadniczo zmodyfikowane kopie/pasty z this tutorial i że używam Lua 5.2:
static int newPoint(lua_State *L)
{
int n = lua_gettop(L);
if (n != 2)
return luaL_error(L, "expected 2 args for Point.new()", n);
// Allocate memory for a pointer to object
Point **p = (Point **)lua_newuserdata(L, sizeof(Point *));
double x = luaL_checknumber (L, 1);
double y = luaL_checknumber (L, 2);
//I want to access this pointer in C++ outside this function
*p = new Point(x, y);
luaL_getmetatable(L, "Point"); // Use global table 'Point' as metatable
lua_setmetatable(L, -2);
return 1;
}
static const luaL_Reg pointFuncs[] = {
{"new", newPoint},
{NULL, NULL}
};
//register Point to Lua
void registerPoint(lua_State *L)
{
lua_createtable(L, 0, 0);
// Register metatable for user data in registry
luaL_newmetatable(L, "Point");
luaL_setfuncs(L, pointFuncs, 0);
lua_pushvalue(L,-1);
lua_setfield(L,-2, "__index");
lua_setglobal(L, "Point");
}
Point* checkPoint(lua_State* L, int index)
{
void* ud = 0;
luaL_checktype(L, index, LUA_TTABLE);
lua_getfield(L, index, "__index");
ud = luaL_checkudata(L, index, "Point");;
return *((Point**)ud);
}
int main()
{
lua_State *L = luaL_newstate();
luaL_openlibs(L);
registerPoint(L);
luaL_dofile(L, "testz.lua");
lua_getglobal(L, "Point");
Point *foo = checkPoint(L, lua_gettop(L));
std::cout << "x: " << foo->x << " y: " << foo->y;
lua_close(L);
return 0;
}
A oto skrypt Lua:
local point = Point.new(10,20)
Uruchomienie tego kodu, pojawia się następujący błąd : "zły argument nr 3 (oczekiwany punkt, otrzymałem tabelę)" na linii: ud = luaL_checkudata (L, indeks, "Punkt") wewnątrz funkcji checkPoint().
Jeśli ktoś mógłby mnie skierować we właściwym kierunku, byłoby to bardzo cenne.
Dokładnie to, co musiałem wiedzieć! 1000x dzięki tobie, proszę pana. – user2687268
@ user2687268 Dodałem notatkę o obsłudze danych użytkownika clean. – greatwolf
to dobre wytłumaczenie, ale wydaje się zakładać, że garbage collector nie uruchomi się, zanim wskaźnik punktowy uzyska punkt od stanu lua. To może nie dotyczyć tego prostego przykładu, ale w bardziej rozbudowanych skryptach nie będziesz wiedział, kiedy gc usunie twój punkt. Stąd całe zamieszanie zarządzania czasem pamięci w bibliotekach wiążących. –