[C++-sig] Boost::python and shared_ptr

Bernhard Glück bernhardprivat at realspace.org
Tue Jan 4 21:45:10 CET 2005

  Hi !

I am using a boost::python to script our newest project.
We use boost::shared_ptr for almost all of our objects.

How do i correctly wrap my classes so that they are held as shared_ptr 
objects and
passed around that way ? I tried doing it like it was posted this 
mailing list
before, but with the following problems.

My environment is as follows::

Python 2.4,
Boost 1.32.0
Compiler: VC7.1

Here the relevant code passages:

First our game object which holds smart pointers to several sub systems:

typedef boost::shared_ptr< class GraphicsServer >        GraphicsServerPtr;
     typedef boost::shared_ptr< class AudioServer > 
     typedef boost::shared_ptr< class ScriptServer > 
     typedef boost::shared_ptr< class InputServer > 
     typedef boost::shared_ptr< class PhysicsServer > 
     typedef boost::shared_ptr< class AiServer >                AiServerPtr;
     typedef boost::shared_ptr< class ConfigurationServer > 
     typedef boost::shared_ptr< class TimeServer >            TimeServerPtr;

     class Game :    public Ogre::Singleton<Game>,
             public Ogre::FrameListener

         const GraphicsServerPtr & GetGraphicsServer() const;
         const AudioServerPtr &      GetAudioServer() const;
         const ScriptServerPtr &      GetScriptServer() const;
         const InputServerPtr &      GetInputServer() const;
         const PhysicsServerPtr &  GetPhysicsServer() const;
         const AiServerPtr &      GetAiServer() const;
         const ConfigurationServerPtr &    GetConfigurationServer() const;
         const TimeServerPtr    & GetTimeServer() const;

         void            Start();
         void            Stop();

         bool    frameStarted(const Ogre::FrameEvent& evt);
         bool    frameEnded( const Ogre::FrameEvent & evt);

         virtual ~Game();


         GraphicsServerPtr        mGraphicsServer;
         AudioServerPtr            mAudioServer;
         ScriptServerPtr            mScriptServer;
         InputServerPtr            mInputServer;
         PhysicsServerPtr        mPhysicsServer;
         AiServerPtr                        mAiServer;
         ConfigurationServerPtr    mConfigurationServer;
         TimeServerPtr        mTimeServer;

         bool            mStop;

Now our configuration server code that stores "registry" style values (
configuration information for our game )

class ConfigurationServer : public Server

         template<typename T>
         inline T GetValue( const std::string & name,T defaultValue )
             if ( mValues.find(name) != mValues.end() )
                 boost::any value = mValues[name];
                 if ( value.type() == typeid(T ))
                 return boost::any_cast<T>(value);
                 boost::format errorFmt("Configuration value
                                 (%1%) of wrong type (%2%),
                                 expected (%3%), using default of (%4%).");
                 errorFmt % name;
                 errorFmt % value.type().name();
                 errorFmt % typeid(T).name();
                 errorFmt % defaultValue;
                 Log( errorFmt.str() );
                 boost::format errorFmt("Configuration value
                                 (%1%) not found, using default of (%2%).");
                 errorFmt % name;
                 errorFmt % defaultValue;
                 Log( errorFmt.str() );
             return defaultValue;

         template<typename T>
         inline void SetValue( const std::string & name,T value )
             mValues[name] = boost::any(value);

         virtual bool        Reset();
         virtual bool        Initialize();
         virtual bool        Shutdown();
         virtual bool        Update( float deltaTime );

         virtual ~ConfigurationServer();


         std::map<std::string,boost::any> mValues;

And now the export part:

void PyExportConfigurationServer()
     Log("Exported configuration server.");
     void (ConfigurationServer::*cm1)( const std::string &,int ) 
     void (ConfigurationServer::*cm2)( const std::string
     void (ConfigurationServer::*cm3)( const std::string &,bool )
     void (ConfigurationServer::*cm4)( const std::string &,std::string )

     register_ptr_to_python< boost::shared_ptr<ConfigurationServer> >();

     class_< ConfigurationServer,boost::shared_ptr<ConfigurationServer> >
("ConfigurationServer",no_init )

void PyExportGame()
DeepVoid::Log("Exported game.");
     class_<Game> ("Game",no_init )
         .def("quit",&Game::Stop )





The problem now is that the game class works as expected but whenever i do
something like this:

import dv
game = dv.getGame()
config = game.getConfigurationServer()

I get the following error:

20:54:20: No Python class registered for C++ class class
20:54:20:   File "DeepVoidConfig.py", line 3, in ?     config =

I have no clue why this could happen. I  tried chaning the export code 
for the
ConfiguratioNServer in various ways ( leaving out register_ptr_to_python,
or the second wrapper definition ) to no avail..

Both classes get exported by the way ( as my log tells me, thats why i have
those two Log statements in the code )....

So what can i do to pass around my objects as shared_ptrs ?
Ideally i would like almost all objects of our engine to be held in
shared_ptr instead of normal ones.

Hope anyone can help :-)
Thanks in advance
Bernhard Glück

More information about the Cplusplus-sig mailing list