TL; DR: у меня есть производное **, которое я храню в Lua как пользовательские данные void *.Затем я пытаюсь вернуть его как базу ** и все ломается.Могу ли я что-нибудь сделать или это все безумие обречено на провал?
Подробности:
Я передаю некоторые данные между Lua и C ++, и Lua требует использованияvoid * для хранения пользовательских данных (то, что я использую Lua, не слишком важно, кроме того, что оно использует указатели void).Имеет смысл до сих пор.Допустим, у меня есть три класса, Base
и Derived
, с Derived
, унаследованными от Base
.Пользовательские данные, которые я передаю Lua, - это указатель на указатель, например:
template <typename T>
void lua_push(L, T* obj) {
T** ud = (T**)lua_newuserdata(L, sizeof(T*)); // Create a new userdata
*ud = obj; // Set a pointer to my object
// rest of the function setting up other stuff omitted
}
Конечно, это хорошая шаблонная функция, поэтому я могу передать любой из трех своих типов таким образом.Позже я могу использовать другую шаблонную функцию для извлечения своих пользовательских данных из Lua, например так:
template <typename T>
T* lua_to(lua_State* L, int index) {
// there's normally a special metatable check here that ensures that
// this is the type I want, I've omitted it for this example
return *(T**)lua_touserdata(L, index);
}
Это прекрасно работает, когда я передаю и выводлю тот же тип.Я столкнулся с проблемой, хотя при попытке вытащить Derived
как Base
.
В моем конкретном случае вектор хранится в Base
.Я использую lua_push<Derived>(L, obj);
, чтобы подтолкнуть мой объект к Луа.Позже, в другом месте, я вытаскиваю его, используя Base* obj = lua_to<Base>(L, i);
.Затем я push_back
некоторые вещи в моем векторе.Позже, другая часть кода извлекает тот же самый объект (проверенный сравнением указателей), за исключением того, что на этот раз объект Derived* obj = lua_to<Derived>(L, i);
My Derived
не видит объект, который был вставлен. Я считаю, что я сузил этоиз-за неправильного приведения, и я, вероятно, где-то повреждаю память, когда я звоню push_back
Итак, мой вопрос, есть ли способ заставить этот приём работать правильно?Я пробовал разные вкусы слепков.static_cast, dynamic_cast и reinterpret_cast не работают, либо дают мне один и тот же неправильный ответ, либо вообще не компилируют.
Конкретный пример:
Base* b = lua_to<Base>(L, -1); // Both lua_to's looking at the same object
Derived* d = lua_to<Derived>(L, -1); // You can be double sure because the pointers in the output match
std::cout << "Base: " << b << " " << b->myVec.size() << std::endl;
std::cout << "Derived: " << d << " " << d->myVec.size() << std::endl;
Вывод:
Base: 0xa1fb470 1
Derived: 0xa1fb470 0