Boost::Python Help

Started by
2 comments, last by slynk 12 years, 6 months ago
I'm desperately trying to expose an instantiated class object to python so that it can access its public functions to initialize it. For example, I instantiated an sMainMenu object menu. I call my python wrapper's Expose_MainMenu(menu); function:



void PythonWrapper::Expose_MainMenu(sMainMenu &menu)
{
try{
main_namespace["sMainMenu"] = boost::python::class_<sMainMenu>("sMainMenu")
.def("LoadImage",&sMainMenu::LoadImage)
.def("LoadSprite", &sMainMenu::LoadSprite)
.def("LoadButton",&sMainMenu::LoadButton);

main_namespace["menu"] = boost::python::ptr(&menu);
}
catch(boost::python::error_already_set const &){
std::string perror_str = parse_python_exception();
std::cout << "Error in Python: " << perror_str << std::endl;
}
}



Now in my python exposure of sMainMenu, I've only defined the functions I want python scripts to have access to... is this a mistake? Is this the reason my application either doesn't do anything or completely crashes? Do I need to define the class with every function and member of the class?

I know if I call the function twice, it'll crash from the double definition of sMainMenu (I'm going to pull it out into a module once it works.) The script is being "executed" by calling:



void PythonWrapper::Execute_Script()
{
try{
PyRun_String("import Main_Menu", Py_file_input, main_namespace.ptr(), main_namespace.ptr());
}
catch(boost::python::error_already_set const &){
std::string perror_str = parse_python_exception();
std::cout << "Error in Python: " << perror_str << std::endl;
}
}



I placed some prints through out the script but only the first one outputs to the command prompt. My script is:



print("Loaded the file...\n")

menu.LoadImage("resources/texture/background.png");
menu.LoadImage("resources/texture/biNewGame.png");
menu.LoadImage("resources/texture/baNewGame.png");
menu.LoadImage("resources/texture/biLoadGame.png");
menu.LoadImage("resources/texture/baLoadGame.png");
menu.LoadImage("resources/texture/biOptions.png");
menu.LoadImage("resources/texture/baOptions.png");
menu.LoadImage("resources/texture/biQuit.png");
menu.LoadImage("resources/texture/baQuit.png");
print("Loaded the images...\n")

menu.LoadSprite(0, 0, 0);
print("Loaded the background...\n")


menu.LoadButton(1, 2, 350, 174);
menu.LoadButton(3, 4, 333, 328);
menu.LoadButton(5, 6, 398, 483);
menu.LoadButton(7, 8, 455, 640);
print("Loaded the buttons...\n")




If I try to use boost::python::exec_file() the game crashes, hence the use instead of PyRun_String()
Advertisement
I placed a cout at the beginning of the LoadImage function and it's not even called. Has to be an issue with my class or object exposure to python.
Alright I switched from an import to the boost::python::exec_file() method. It was crashing because I passed the pile name with the .py extension, when I removed it, it threw an error message before crashing:



Error in Python: <class 'SyntaxError'>: ('invalid character in identifier', ('Ma
in_Menu', 1, 3, '?????????\x04x\x18???\x04????????????'))

This application has requested the Runtime to terminate it in an unusual way.
Please contact the application's support team for more information.

Process returned 3 (0x3) execution time : 98.969 s
Press any key to continue.




Any help? :(
I think it may be due to inheritance issues as sMainMenu is derived of sMenu which is derived of GameState... I'm not really sure how to wrap it all up:

GameState:


class GameState
{
public:
virtual const void Init(GameStateManager* g) = 0;
virtual const void Cleanup() = 0;

virtual const void Pause() = 0;
virtual const void Resume() = 0;

virtual const void HandleEvents() = 0;
virtual const void Update() = 0;
virtual const void Draw(sf::RenderWindow* window) = 0;

void ChangeState(GameState* state);

/// Utility functions for Python mostly
void LoadImage(std::string path);
void LoadSprite(int textureNum, int x, int y);

protected:
std::vector<sf::Texture> textures;
std::vector<sf::Sprite> sprites;
std::vector<sf::Text> text;
GameStateManager* game;
bool isPaused;

};


sMenu:


class sMenu : public GameState
{
public:
virtual const void Init(GameStateManager* g);
const void Cleanup();

const void Pause(){isPaused = true;}
const void Resume(){isPaused = false;}

const void HandleEvents();
const void Update();
const void Draw(sf::RenderWindow* window);

///Utility functions mostly for Python
void LoadButton(int textureI, int textureA, int x, int y);

protected:
std::vector<Button> buttons;
int selected;
virtual const void toDo(int which) = 0;
};


sMainMenu:


class sMainMenu : public sMenu
{
public:
virtual const void Init(GameStateManager* g);

const void toDo(int which);
};

This topic is closed to new replies.

Advertisement