nềnLua, C++ và metatables biến mất
tôi làm việc với Watusimoto vào trò chơi Bitfighter. Chúng tôi sử dụng một biến thể của LuaWrapper để kết nối các đối tượng C++ của chúng ta với các đối tượng Lua trong game. Chúng tôi cũng sử dụng một biến thể của Lua được gọi là lua-vec để tăng tốc hoạt động vector.
Chúng tôi đã cố gắng giải quyết một lỗi trong một khoảng thời gian đã bỏ qua chúng tôi. Các sự cố ngẫu nhiên sẽ xảy ra cho thấy các metatables hỏng. Xem here cho bài đăng của Watusimoto về vấn đề này. Tôi không chắc nó là vì một metatable tham nhũng và đã thấy một số hành vi thực sự kỳ lạ về mà tôi muốn hỏi ở đây.
Vấn đề biểu hiện
Như một ví dụ, chúng ta tạo ra một đối tượng và thêm nó vào một mức độ như thế này:
t = TextItem.new()
t:setText("hello")
levelgen:addItem(t)
Tuy nhiên, các trò chơi sẽ thỉnh thoảng (không phải luôn luôn) sụp đổ. Với một lỗi:
attempt to call missing or unknown method 'addItem' (a nil value)
Sử dụng một gợi ý được đưa ra trong câu trả lời cho bài Watusimoto đã đề cập ở trên, tôi đã thay đổi dòng cuối cùng như sau:
local ok, res = pcall(function() levelgen:addItem(t) end)
if not ok then
local s = "Invalid levelgen value: "..tostring(levelgen).." "..type(levelgen).."\n"
for k, v in pairs(getmetatable(levelgen)) do
s = s.."meta "..tostring(k).." "..tostring(v).."\n"
end
error(res..s)
end
này in ra metatable cho levelgen
nếu có điều gì khi gọi sai phương thức từ nó.
Tuy nhiên, điều này thật điên rồ, khi không thành công và in ra tính khả thi, metatable là chính xác như thế nào (với cuộc gọi addItem
và mọi thứ chính xác). Nếu tôi in các metatable cho levelgen
khi tải tập lệnh, và khi nó không sử dụng pcall
ở trên, họ là giống hệt nhau, mọi cuộc gọi và con trỏ đến userdata là như nhau và như nó phải được.
Điều đó giống như việc có thể làm cho số ngẫu nhiên cho levelgen
tự động biến mất một cách ngẫu nhiên.
Có ai có ý tưởng gì đang xảy ra không?
Cảm ơn bạn
Lưu ý: này không xảy ra chỉ với những đối tượng levelgen
. Ví dụ, nó đã xảy ra trên đối tượng TestItem
được đề cập ở trên là tốt. Trong thực tế, đó là mã cùng bị treo trên máy tính của tôi tại dòng levelgen:addItem(t)
nhưng tai nạn trên máy tính của nhà phát triển khác với dòng t:setText("hello")
với thông báo lỗi tương tự missing or unknown method 'setText' (a nil value)
Bạn đã thử chạy mã của mình trong Valgrind chưa? Bạn có thể có một vấn đề tham nhũng bộ nhớ từ C + +. – nneonneo
Xin chào, vâng, chúng tôi đã chạy nó thông qua valgrind nhiều lần ngay bây giờ, và sau khi sửa chữa các lỗi bộ nhớ đã có (trong mã không liên quan) vấn đề vẫn còn tồn tại – raptor
Rất tò mò. Bạn có thể giảm vấn đề xuống một testcase ngắn không? – nneonneo