Advertisement

Luabind crashes...

Started by May 11, 2011 07:30 PM
7 comments, last by MatsK 13 years, 6 months ago
Any idea why the following makes LuaBind crash?

//Makes the SceneManager object available to all Lua scripts.
luabind::globals(LuaInterfaceManager::LuaManager)["SceneManager"] = SceneMgr;

//Makes the UIScene available to all Lua scripts.
luabind::module(LuaInterfaceManager::LuaManager)[luabind::class_<UIScene>("UIScene").def(
luabind::constructor<SceneManager, std::string>()).def("LoadBackground", &UIScene::LoadBackground)];



I'm not exactly sure why, but they both make LuaBind crash horribly. I tried commenting out each of them in turn, and they both cause a crash.

Here's what the UIScene class looks like:

#ifndef __UISCENE_H__
#define __UISCENE_H__

#pragma once

#include <vector>
#include <string>
#include "UIBackground.h"
#include "SceneManager.h"
#include "libfar.h"

using namespace std;

class UIScene
{
private:
string m_ArchivePath;
SceneManager m_SceneMgr;

vector<UIBackground> m_Backgrounds;
public:
UIScene(SceneManager SceneMgr, string ArchivePath);
void LoadBackground(int ID);
};

#endif



#include "stdafx.h"
#include "UIScene.h"

UIScene::UIScene(SceneManager SceneMgr, string ArchivePath)
{
m_SceneMgr = SceneMgr;
m_ArchivePath = ArchivePath;
}

void UIScene::LoadBackground(int ID)
{
unsigned char *Destination;
sf::Image Img;

unsigned int NumBytes = ExtractItemFromFARByID((char *)m_ArchivePath.c_str(), (unsigned long)ID, &Destination, 0);
Img.LoadFromMemory((const char*)Destination, NumBytes);

UIBackground Background(Img);
m_Backgrounds.push_back(Img);
}



Here's the SceneManager class:

#ifndef __SCENEMANAGER_H__
#define __SCENEMANAGER_H__

#pragma once

#include <vector>
#include <string>
#include <log4cplus/logger.h>
#include <log4cplus/configurator.h>

using namespace log4cplus;
using namespace std;

//Forward declaration, to avoid having to include "UIScene.h".
class UIScene;

class SceneManager
{
private:
vector<UIScene> m_Scenes;
public:
void LoadInitialScreen(string Path);
};

#endif



#include "stdafx.h"
#include "SceneManager.h"
#include "LuaInterfaceManager.h"

void SceneManager::LoadInitialScreen(std::string Path)
{
if(luaL_dofile(LuaInterfaceManager::LuaManager, Path.c_str()) != 0)
{
Logger Log = Logger::getInstance((log4cplus::tstring&)"SceneManager");
LOG4CPLUS_ERROR(Log, lua_tostring(LuaInterfaceManager::LuaManager, -1));
}
}



The first LuaBind statement causes the program to crash into luabind/class_cache.hpp at the following:

#else

template<class T>
class_rep* get_class_rep(lua_State* L, void(*)(T*) = 0)
{
class_registry* registry = class_registry::get_registry(L);
return registry->find_class(LUABIND_TYPEID(T));
}

#endif

Does you have other bindings in your code that do work? Is it crashing when the binding code is executing, or when the bound code is being called from within Lua? Are you making sure that ownership of bound objects is being handled correctly? (Ie, Lua isn't using its automatic garbage collection on your engine manager objects is it?)


I don't see anything wrong after a cursory glance. Here's some equivalent code from Allacrost that achieves the same effect (and works):

Binding global class objects:

luabind::object global_table = luabind::globals(hoa_script::ScriptManager->GetGlobalState());
global_table["AudioManager"] = hoa_audio::AudioManager;
global_table["InputManager"] = hoa_input::InputManager;
global_table["ModeManager"] = hoa_mode_manager::ModeManager;
global_table["ScriptManager"] = hoa_script::ScriptManager;
global_table["SystemManager"] = hoa_system::SystemManager;
global_table["VideoManager"] = hoa_video::VideoManager;


Binding a class:

module(hoa_script::ScriptManager->GetGlobalState(), "hoa_system")
[
def("Translate", &hoa_system::Translate),

class_<SystemTimer>("SystemTimer")
.def(constructor<>())
.def(constructor<uint32, int32>())
.def("Initialize", &SystemTimer::Initialize)
.def("EnableAutoUpdate", &SystemTimer::EnableAutoUpdate)
.def("EnableManualUpdate", &SystemTimer::EnableManualUpdate)
.def("Update", (void(SystemTimer::*)(void)) &SystemTimer::Update)
.def("Update", (void(SystemTimer::*)(uint32)) &SystemTimer::Update)
.def("Reset", &SystemTimer::Reset)
.def("Run", &SystemTimer::Run)
.def("Pause", &SystemTimer::Pause)
.def("Finish", &SystemTimer::Finish)
.def("IsInitial", &SystemTimer::IsInitial)
.def("IsRunning", &SystemTimer::IsRunning)
.def("IsPaused", &SystemTimer::IsPaused)
.def("IsFinished", &SystemTimer::IsFinished)
.def("CurrentLoop", &SystemTimer::CurrentLoop)
.def("TimeLeft", &SystemTimer::TimeLeft)
.def("PercentComplete", &SystemTimer::PercentComplete)
.def("SetDuration", &SystemTimer::SetDuration)
.def("SetNumberLoops", &SystemTimer::SetNumberLoops)
.def("SetModeOwner", &SystemTimer::SetModeOwner)
.def("GetState", &SystemTimer::GetState)
.def("GetDuration", &SystemTimer::GetDuration)
.def("GetNumberLoops", &SystemTimer::GetNumberLoops)
.def("IsAutoUpdate", &SystemTimer::IsAutoUpdate)
.def("GetModeOwner", &SystemTimer::GetModeOwner)
.def("GetTimeExpired", &SystemTimer::GetTimeExpired)
.def("GetTimesCompleted", &SystemTimer::GetTimesCompleted),
];

Hero of Allacrost - A free, open-source 2D RPG in development.
Latest release June, 2015 - GameDev annoucement

Advertisement
[color="#1C2837"]
or when the bound code is being called from within Lua? Are you making sure that ownership of bound objects is being handled correctly? (Ie, Lua isn't using its automatic garbage collection on your engine manager objects is it?)[/quote]

[color="#1C2837"]
[color="#1C2837"]Nope. I'm not even running any Lua code as of yet. :(
IIRC
LuaInterfaceManager::LuaManager is not a part of LuaBind , i'm guessing that this is your Lua State though.

I had a similar crash that was caused by me not calling luabind::open(myownluastate); before i used luabind::module.
You should also create your lua state using lua_open (and close it using lua_close)

Thus you want to do:

lua_State *L = lua_open();
luabind::open(L);

...

luabind::module(L) ....

not calling luabind::open will result in a segmentation fault.

(If you recieve your lua state from the lua runtime you don't have to create your lua state using lua_open() but you still have to call luabind::open on it)
[size="1"]I don't suffer from insanity, I'm enjoying every minute of it.
The voices in my head may not be real, but they have some good ideas!
Yeah I fixed it! :)
I had put lua_open() and luabin::open() inside the constructor for LuaInterfaceManager. I assumed that I had made LuaInterfaceManager static and that the constructor was calling itself, but then I realized that static classes aren't even allowed in C++. :\ So I had to call the constructor manually.
Ok so after fiddling around I've gotten logging to work.
Lua reports:

scenemanager.cpp (00011): , [SceneManager::LoadInitialScreen], [s_0] [Mon May 16 18:18:16 2011], Error encountered in Lua script: gamedata\luascripts\personselection.lua:6: attempt to call global 'UIScreen' (a nil value)

Why is this happening? :(

Here are my three lines of Lua so far:

PersonSelectionScreen = UIScreen('uigraphics\\personselection\\personselection.dat')
ScreenMgr:AddScreen(PersonSelectionScreen)

PersonSelectionScreen:LoadBackground(0x3FA)



And here is the function I made to register classes:

//Registers all neccessary classes so that they are available to use
//when scripting in Lua.
void LuaInterfaceManager::RegisterClasses()
{
//Make the SceneManager class available to Lua.
luabind::module(LuaInterfaceManager::LuaManager)
[luabind::class_<SceneManager>("SceneManager")
.def(
luabind::constructor<>())
.def("LoadInitialScreen", &SceneManager::LoadInitialScreen)];

//Makes the UIScene class available to all Lua scripts.
luabind::module(LuaInterfaceManager::LuaManager)
[luabind::class_<UIScene>("UIScene")
.def(luabind::constructor<std::string>())
.def("LoadBackground", &UIScene::LoadBackground)];
}



Help!
Advertisement
Of course it doesn't. You bound the code to "UIScene" yet in your script you are calling "UIScreen".

Hero of Allacrost - A free, open-source 2D RPG in development.
Latest release June, 2015 - GameDev annoucement


Ok so after fiddling around I've gotten logging to work.
Lua reports:

scenemanager.cpp (00011): , [SceneManager::LoadInitialScreen], [s_0] [Mon May 16 18:18:16 2011], Error encountered in Lua script: gamedata\luascripts\personselection.lua:6: attempt to call global 'UIScreen' (a nil value)

Why is this happening? :(

Here are my three lines of Lua so far:

PersonSelectionScreen = UIScreen('uigraphics\\personselection\\personselection.dat')
ScreenMgr:AddScreen(PersonSelectionScreen)

PersonSelectionScreen:LoadBackground(0x3FA)



And here is the function I made to register classes:

//Registers all neccessary classes so that they are available to use
//when scripting in Lua.
void LuaInterfaceManager::RegisterClasses()
{
//Make the SceneManager class available to Lua.
luabind::module(LuaInterfaceManager::LuaManager)
[luabind::class_<SceneManager>("SceneManager")
.def(
luabind::constructor<>())
.def("LoadInitialScreen", &SceneManager::LoadInitialScreen)];

//Makes the UIScene class available to all Lua scripts.
luabind::module(LuaInterfaceManager::LuaManager)
[luabind::class_<UIScene>("UIScene")
.def(luabind::constructor<std::string>())
.def("LoadBackground", &UIScene::LoadBackground)];
}



Help!


Nvm, looks like it was a typo, Roots caught it.
[size="1"]I don't suffer from insanity, I'm enjoying every minute of it.
The voices in my head may not be real, but they have some good ideas!
D'oh!
Thanks :)

This topic is closed to new replies.

Advertisement