🎉 Celebrating 25 Years of GameDev.net! 🎉

Not many can claim 25 years on the Internet! Join us in celebrating this milestone. Learn more about our history, and thank you for being a part of our community!

Boost.Python problem

Started by
8 comments, last by Toni Petrina 20 years, 11 months ago
I''m using python for about 4 hours and I''m frustrated. It seems that I can''t do anything with it. Anway, here is the code (C++ using Boost.Python).

#include <windows.h>
#include <iostream>
#include <stdio.h>

#include <boost/python.hpp>
#include <boost/python/handle.hpp>

using namespace boost::python;
using namespace std;

char const *Greet() {
	return "Helo world!";
}

BOOST_PYTHON_MODULE(mymodule)
{
	def("greet", Greet);
}

int main() {
	Py_Initialize();
	// am I supposed to do this?

	init_module_mymodule();

	handle<> main_module(borrowed(PyImport_AddModule("__main__")));
	handle<> main_namespace(borrowed((PyModule_GetDict(main_module.get()))));
	handle<>( PyRun_String( "import mymodule\n"
							"print mymodule.greet()"
							, Py_file_input,
							main_namespace.get(), main_namespace.get()) );

	if (Py_IsInitialized())
		Py_Finalize();
	return 0;
}
Does anyone know where is the problem? I don''t want to put everyhing into separate dll, I just need to use it inside my program.
So... Muira Yoshimoto sliced off his head, walked 8 miles, and defeated a Mongolian horde... by beating them with his head?

Documentation? "We are writing games, we don't have to document anything".
Advertisement
I explained this a long time ago, but unfortunately, they delete the posts after a while... Anyway, what you DON'T want to do is call init_module_%%() (in your case, init_module_mymodule()), but instead, if you look inside the header files, call init_%%() instead (notice the lack of 'module'). So replace the init_module_mymodule() line with init_mymodule() and tell us if it works.

EDIT: if this doesn't work, it has to do with the way you're executing the code. I don't understand why you're importing the '__main__' module and retrieving the dictionary. There's another RunString() function that takes care of that by providing default values. But hey, if it works, whatever floats your boat.

Chris Pergrossi
My Realm | "Good Morning, Dave"

[edited by - c t o a n on August 1, 2003 7:54:06 AM]
Chris PergrossiMy Realm | "Good Morning, Dave"
I actually read that thread for about 10 timed without getting it. Anyway, I was trying to implemet your idea when I got sick of MSVC6. It compiles boost/python.hpp for 1.5 minutes. So I tried to put it into stdafx.h and make some use of precompiled header but then it gives me INTERNAL_COMPILER_ERROR somwhere in ref.hpp, god-knows-where. But when I put it into .cpp file, it compiles with no problem, only it takes 1.5 minutes to compile. Did you have that sort of errors? Here is the code which compiler fails to compile.
// source from ref.hpptemplate<class T> class reference_wrapper{ public:    typedef T type;#if defined(BOOST_MSVC) && (BOOST_MSVC < 1300)    explicit reference_wrapper(T& t): t_(&t) {}#else    explicit reference_wrapper(T& t): t_(addressof(t)) {}#endif    operator T& () const { return *t_; }    T& get() const { return *t_; }[b]break[/b]----> T* get_pointer() const { return t_; }private:    T* t_;};

Please help.
So... Muira Yoshimoto sliced off his head, walked 8 miles, and defeated a Mongolian horde... by beating them with his head?

Documentation? "We are writing games, we don't have to document anything".
Start a python interpreter in your project directory and type ''import mymodule'' then ''print ''mymodule.greet()''. If that fails, you haven''t built the extension module properly (which, afaik, must be in a seperate dll (in python, .dll''s end in .pyd)).

Try putting the extension into its own file (everything except main()) and building that with ''bjam -sTOOLS=msvc'' at the command line. Then build your exe from within MSVC (everything except the extension, ie main()). You should have a mymodule.pyd and an executable. Put mymodule.pyd in the same dir as the executable (it is buried in the boost/libs/python directory) and run.
#include <windows.h>#include <boost/python.hpp>using namespace boost::python;char const *Greet() {	return "Helo world!";}BOOST_PYTHON_MODULE(pytest){	def("greet", Greet);}

This little dll has pch file of size 35 MB!!!! How can this be? And it compiles about one minute.

So... Muira Yoshimoto sliced off his head, walked 8 miles, and defeated a Mongolian horde... by beating them with his head?

Documentation? "We are writing games, we don't have to document anything".
It works now but it is still so slow. Are you using python? How fast is compilation at your system?
So... Muira Yoshimoto sliced off his head, walked 8 miles, and defeated a Mongolian horde... by beating them with his head?

Documentation? "We are writing games, we don't have to document anything".
When I compile any CPP file with boost/python included it DOES take forever, but you know why? The COMPILER is allocating/deallocating memory like no other! When it can''t do this properly, it says "INTERNAL COMPILER ERROR: Ran Out of Memory". The way to get around this (and make it a WHOLE LOT FASTER) is to increase your compiler''s stack size by using the /Zm option. Put /Zm200 (which means 200% of the usual size) to get pretty good sizes, though watch out, cause MSDN warns that the default compiler stack size (though it doesn''t use all of it) is 100 MB, so if you do 200% that''s 200 megs! I''ve got 512 of RAM so I don''t notice if this is true or not, but just telling ya to watch out for it. And did you get the external module thing to work? Oh yeah, and a point to note, when you use the Boost:ython library, it uses templates and run time information like no other, causing the memory usage to shoot through the roof. Therefore, if you put lots of modules (or lots of functions/classes in modules) IN THE SAME FILE [.cpp] (different files don''t matter) then you''re going to have to increase the stack size AGAIN. If you get this problem again, try spreading you''re modules among different cpp files. Good luck!

Chris Pergrossi
My Realm | "Good Morning, Dave"
Chris PergrossiMy Realm | "Good Morning, Dave"
And to get the external modules to work, here's a snip from one of my early experiments to embed python in my engine:

#ifdef _DEBUG#undef _DEBUG#include <Python.h>#include <Boost/Python.h>#define _DEBUG#endif#include <iostream.h>#include <conio.h>#include <stdio.h>using namespace boost::python;#pragma comment( lib, "boost_python.lib" )class CBlah{public:	CBlah( char* name ) { strcpy( Name, name ); }	void SetName( char* name ) { strcpy( Name, name ); }	const char* GetName() const { return Name; }	void Print( char* begin ) { cout << begin << Name << "\n"; cout.flush(); }protected:	char Name[32];};static CBlah something( "Joe" );void Click( char* string ){	cout << "Hello " << string << "!\n";}CBlah& GetSomething(){	return something;}BOOST_PYTHON_MODULE(mouse){	class_<CBlah>( "CBlah", init<char*>() )		.def( "SetName", &CBlah::SetName )		.def( "Print", &CBlah::Print )		.add_property( "Name", &CBlah::GetName );	def( "Click", Click );	def( "GetSomething", GetSomething, return_value_policy<reference_existing_object>() );}void main( void ){	cout << "Simple Embedded Python v1.0\n";	cout << "Chris Pergrossi\n\n";	// app variables	FILE* fp = NULL;	char  fileName[ 128 ];	// Python variables	object File, Module, Dict, Func;	// get the script file name	cout << "Python File: ";	cin  >> fileName;	cout << "\n";	cout.flush();	// initialize Python and import the script	Py_Initialize();	PyRun_SimpleString( "import sys" );	PyRun_SimpleString( "sys.path.append( 'C:/Developer/Scripts/' )" );	File = object( handle<>( borrowed( PyString_FromString( fileName ) ) ) );	// but first, add the 'mouse' module to Python	initmouse();	// build the objects	object blah = object( CBlah( "Chri" ) );/*(class_<CBlah>( "CBlah", init<char*>() )					.def( "SetName", &CBlah::SetName )					.def( "Print", &CBlah::Print ))( "Chris" );*/	object add = object( "s" );	// now import the script	Module = object( handle<>( PyImport_Import( File.ptr() ) ) );	handle<>( PyImport_Import( File.ptr() ) );	// if the script was loaded...	if( Module )	{		// get the dictionary (borrowed reference!)		Dict = object( handle<>( borrowed( PyModule_GetDict( Module.ptr() ) ) ) );		// get the 'Create' function (borrowed)		Func = object( handle<>( borrowed( PyDict_GetItemString( Dict.ptr(), "Create" ) ) ) );		if( Func && PyCallable_Check( Func.ptr() ) )		{			//Args = PyTuple_New( 0 );			//Args = Py_BuildValue( "O", blah.ptr() );			// call the function			if( !handle<>(PyObject_CallFunction( Func.ptr(), "OO", blah.ptr(), add.ptr())) )				cout << "Couldn't Call The Function\n";			//Py_DECREF( Args );		}		else		{			PyErr_Print();			cout << "Couldn't Find The Function\n";		}	}	else	{		PyErr_Print();		cout << "Couldn't Load The Module\n";	}	cout << "\n[Script Complete]\n";	cout.flush();	getch();	Py_Finalize();	// exit(0);}


And I lost my script file, so I can't show you that, but here's what I remember it to be like (and it works, oh yeah!):

import mousedef Create( object, add ):	final = object.Name + add	print final


And I noticed a discrepency between my first post and what I've done now. The correct syntax to 'export' a module to Python that's in the same application as the interpreter (i.e. you don't want to create a seperate DLL for the module), you would do initsomename(). Like above, I did initmouse() where the module is called 'mouse'. Get it? Good luck anyway!

Chris Pergrossi
My Realm | "Good Morning, Dave"

[edited by - c t o a n on August 3, 2003 5:07:06 AM]
Chris PergrossiMy Realm | "Good Morning, Dave"
[offtopic]
c t o a n, thanks for tip and for example (though it didn''t help me much cause I have 192MB SDRAM only). It seems that it''s time for me to spend some money. One question though, if you are going to split classes exports in several cpp files, how are you going to call their functions(initmouse, initthis, initthat)?

How long have you been using Python and for what purpouse? I am just a newbie to this section.
So... Muira Yoshimoto sliced off his head, walked 8 miles, and defeated a Mongolian horde... by beating them with his head?

Documentation? "We are writing games, we don't have to document anything".
In the header file of each .cpp file (which I break the modules into), I have a function declaration like this:

extern "C" {        // the module is called ''kernel''	extern void __declspec(dllexport) initkernel();}


And no problems for the tips (sorry they didn''t help, though you COULD set the ram at /Zm150 or similar, and it would take about 150 megs of RAM, which would work for you I suppose), we''re all here to help those who actually need it (lamers needn''t apply). I''m currently using a system like superpig described in his Enginuity articles here on gamedev.net, but instead of writing the events in C++, which would cause me to have to derive a class each time I needed a new event, I merely write the code in Python, and export the required functions from Python (e.g. ''Create'', ''Update'', ''Stop'', ''Pause'', ''Unpause'', etc.) and export my entire (external of course, not stuff like rendering, which is far too CPU intensive for anything but pure C++) engine interface to Python (using the above described method) so these functions called be called from within my scripts. At engine startup, I scan a specified directory for engine scripts (*.py, *.pyc), which I load and retrieve their respective API''s, then I scan for game specific events (LoadMenu, LoadSinglePlayer, Exit, etc.) in another director (to keep them seperate). In the final distributable, I utilize my already existing .ZIP file archive system to package the Python scripts into one neat little archive, and then use the libraries that come with Python (pretty cool eh?) to extract and load these scripts FROM WITHIN the .ZIP. It even supports compression, which is pretty nice when you have alot of scripts... I''ve been using Python for about a month now, and it works really well, given the flexibility of not recompiling my engine every second.

Chris Pergrossi
My Realm | "Good Morning, Dave"
Chris PergrossiMy Realm | "Good Morning, Dave"

This topic is closed to new replies.

Advertisement