Golp Python extension: convert C++ property classes to Python property classes using Boost.Python

Details

  • Python property module is also named as "golp".
    BOOST_PYTHON_MODULE(golp) {
    	...
    }
    
  • the base class Property is exposed to Python as the base class.
    	class_<Property<double>, boost::noncopyable>("Property", no_init);
    
  • class PyProperty derives from Property and overrides the pure virtual functions. It is exposed to Python as "PyProperty", so property classes can be defined in Python by deriving from PyProperty.
            template<typename T_>
            class PyProperty : public Property<T_> {
            public:
                    PyProperty(const std::string& name) : Property<T_>(name) {}
                    // override pure virtual functions
                    virtual const char *Formula() const { return "Unknow"; }
                    virtual const char *Description() const { return "Unknow"; }
            };
    	
    
  • In order to call back functions overrided in Python, each property class must have a wrapper class, including PyProperty. The wrapper class is defined as a template class.
    	template<class PC_>
    	class Property_Wrapper : public PC_ {
    		PyObject* _self;
    	public:
    		typedef typename PC_::value_type value_type;
    
    		Property_Wrapper(PyObject* self) : _self(self) {} 
    
    		value_type get_rho() const {						
    			return python::call_method<value_type>(_self, "get_rho");	
    		}								
    		static value_type default_get_rho(PC_* p) {				
    			return p->PC_::get_rho();				
    		}
    
    		value_type get_nu() const {						
    			return python::call_method<value_type>(_self, "get_nu");	
    		}								
    		static value_type default_get_nu(PC_* p) {				
    			return p->PC_::get_nu();				
    		}
    		...
    	};
    
    
  • expose property classes to Python by writing a corresponding Boost.Python C++ Wrapper, and expose every interface functions.
    	class_<DryAir<double>, Property_Wrapper<DryAir<double> >, bases<Property<double> >, 
    		boost::noncopyable>("DryAir")
    		.def("get_rho", &Property_Wrapper<DryAir<double> >::default_get_rho)
    		.def("get_nu", &Property_Wrapper<DryAir<double> >::default_get_nu)
    		...
    
    

    requirement and buiding

    buiding golp Python module need Boost 1.29 including Boost.Python v2, and Python 2.2 or newer.
    Golp.Python can be built with the compilers that can build Boost.Python v2. Only gcc 2.95 on linux and MinGW(gcc 3.2) on windows are tested. Here are the make files.

  • gcc 2.95 on linux
    #
    LIBDIR = ../examples/python
    PYTHON_ROOT = /usr/local
    PYTHON_VERSION = 2.2
    BOOST_ROOT = /usr
    GOLP_ROOT = ../golp
    #
    # module specification
    NAME = golp
    LIBVERSION = 1.29.0
    #
    CPP = g++#-3.2
    #CPPFLAGS = -ftemplate-depth-100  -DNDEBUG  -O3 -Wno-inline -fPIC 
    CPPFLAGS = -ftemplate-depth-100 -fPIC -DNDEBUG -Wall \
    	   -I$(PYTHON_ROOT)/include/python$(PYTHON_VERSION) -I$(BOOST_ROOT)/include \
    	   -I$(GOLP_ROOT)
    LDFLAGS =  -s -fPIC -shared -Wl,-rpath-link,. "-Wl,-soname,$(SONAME)" \
    	   -L$(PYTHON_ROOT)/lib/python$(PYTHON_VERSION)/config -lutil \
    	   -L/usr/local/lib -lboost_python -lc
    
    OBJS = pygolp.o 
    SONAME = $(NAME).so.$(LIBVERSION)
    
    .cpp.o:
    	$(CPP) $(CPPFLAGS) -c $<
    
    all: $(SONAME)
    
    $(SONAME) : $(OBJS)
    	$(CPP) $(LDFLAGS) $^ -o $@
    	ln -sf $(SONAME) $(NAME).so
    
    install:
    	cp -f $(SONAME) $(LIBDIR)
    	ln -sf $(SONAME) $(LIBDIR)/$(NAME).so
    
    clean:
    	rm -f $(SONAME) $(NAME).so *.o core
    
    
  • MinGW(gcc 3.2) on windows
    #
    LIBDIR = ../examples/python
    PYTHON_ROOT = d:\python22
    PYTHON_VERSION = 2.2
    BOOST_ROOT = d:\boost_1_29_0
    MINGW_ROOT = d:\MinGW
    GOLP_ROOT = d:\home\work\xuxh\golp\golp
    #
    # module specification
    NAME = golp
    LIBVERSION = 1.29.0
    #
    CPP = g++
    CPPFLAGS = -ftemplate-depth-100 -DNDEBUG -O3 \
    	   -I$(BOOST_ROOT) -I$(PYTHON_ROOT)/include -I$(GOLP_ROOT)
    LDFLAGS = -L$(MINGW_ROOT)/lib -lpython22 -lboost_python
    
    OBJS = pygolp.o 
    DLLNAME = $(NAME).dll
    
    .cpp.o:
    	$(CPP) $(CPPFLAGS) -c $<
    
    all: $(DLLNAME)
    
    $(DLLNAME) : $(OBJS)
    	dllwrap --output-lib=lib$(NAME).a --dllname=$(NAME).dll --driver-name=g++ $(OBJS) $(LDFLAGS)
    
    install:
    	cp -f $(SONAME) $(LIBDIR)
    	ln -sf $(SONAME) $(LIBDIR)/$(NAME).so
    
    clean:
    	rm -f $(DLLNAME) *.o core
    
    

    allan xu, 2002-11-3