crash on table.insert call in virtual Lua function called from C++
Willi <[email protected]>
| Newsgroups | gmane.comp.lang.lua.bind.user |
|---|---|
| Message-ID | <[email protected]> |
Hello, I just tracked down a crash in my program and was able to reproduce it in a simple test program. I inherit from a C++ class via Lua and overwrite a virtual function. In there I call table.insert. If the function is called directly via Lua, everything works, but if it is called from C++, i.e. via luabind::wrap_base::call(), it crashes. Source code is included. A workaround is using "myTable[#myTable] = value", I'm going to do that for now. (Of course that's not the exact behaviour of table.insert, but close enough for my needs.) So long, Willi "Mr. Wonko" Schinmeyer ------------------------------------------------------------------------------ The ultimate all-in-one performance toolkit: Intel(R) Parallel Studio XE: Pinpoint memory and threading errors before they happen. Find and fix more than 250 security defects in the development cycle. Locate bottlenecks in serial and parallel code that limit performance. http://p.sf.net/sfu/intel-dev2devfeb _______________________________________________ luabind-user mailing list [email protected] https://lists.sourceforge.net/lists/listinfo/luabind-user
main.cpp
(text/plain, 2 KB)
//A simple program reproducing a crash I experienced earlier.
// - Willi "Mr. Wonko" Schinmeyer
#include <iostream>
#include <lua.hpp>
#include <luabind/luabind.hpp>
#include <luabind/wrapper_base.hpp>
#include <cassert>
#include <string>
extern "C"
{
#include <lauxlib.h>
}
//I inherit from this class in Lua.
struct myClass
{
//This is used to call the virtual function from C++
void CallVirtual(const std::string& foo) { Virtual(foo); }
//Calling this method directly from Lua works. The parameter isn't necessary to reproduce the crash, it just helps with debug output.
virtual void Virtual(const std::string& foo) = 0;
};
//Lua wrapper class
struct myClassLua : myClass, luabind::wrap_base
{
void Virtual(const std::string& foo) { call<void>("Virtual", foo); }
static void StaticVirtual(myClass& mc, const std::string& foo) { mc.Virtual(foo); }
};
int main()
{
//initialize
lua_State* L = lua_open();
assert(L);
luaL_openlibs(L);
luabind::open(L);
//export via luabind
luabind::module(L)
[
luabind::class_<myClass, myClassLua>("myClass")
.def(luabind::constructor<>())
.def("Virtual", &myClass::Virtual, &myClassLua::StaticVirtual)
.def("CallVirtual", &myClass::CallVirtual)
];
//the lua code
std::string str = "\
class 'myClassLua' (myClass) \n\
\n\
function myClassLua:__init() \n\
myClass.__init(self) \n\
end \n\
\n\
function myClassLua:Virtual(foo) \n\
local tab = {} \n\
print(foo) \n\
table.insert(tab, 1) \n\
print('table.insert called.') \n\
end \n\
\n\
local obj = myClassLua() \n\
obj:Virtual('Works') -- works \n\
obj:CallVirtual('Crashes') -- crashes \n\
print('Didn\\'t crash?') \n\
";
//execute the lua code
if(luaL_loadbuffer(L, str.c_str(), str.size(), "string")||lua_pcall(L, 0, 0, 0))
{
//return != 0 means error.
//the error is pushed onto the stack.
std::cout<<lua_tostring(L, -1)<<std::endl;
}
return 0;
}