[C++-sig] Wrap a virtual function which returns a raw pointer

Birgir Sigurjonsson birgir.sigurjonsson at roxar.com
Thu Dec 21 16:30:27 CET 2006


Hi all.
How can I wrap a  virtual function which returns a raw pointer
which will be managed from C++.

I am embedding Python in my C++ application and
I have the follwoing classes that I want to wrap in boost.python:


In the code below the virtual function ALFactory::make() returns a pointer
to an abstract class AL which is also wrapped with boost.python.
I want to be able to override make() in python and in the
implementation of this function create and return a new python
subclass of my C++ AL. The lifetime of the created object is managed
by the ALFactory.


class ALFactory : private boost::noncopyable {
public:

   ALFactory(const std::string& key);
   virtual ~ALFactory();

   virtual  AL* make() = 0;

};

class AL : private boost::noncopyable {
public:
   virtual ~AL();
protected:
   AL();

};

################ Wrap classes
class ALWrap : public AL, public boost::python::wrapper<AL> {
public:
   ALWrap() : AL() {}
};

class ALFactoryWrap : public ALFactory, public boost::python::wrapper<ALFactory> {
public:
   ALFactoryWrap(const std::string& key) : ALFactory(key) {}
   AL* make() {
     return this->get_override("make")();
   }
};


############
BOOST_PYTHON_MODULE(import_framework) {
     class_<ALWrap, boost::noncopyable>("AL")
     ;

     class_<ALFactoryWrap, boost::noncopyable>("ALFactory", init<std::string>())
         .def("make",  pure_virtual(&ALFactory::make), return_value_policy<manage_new_object>())
     ;
}
###############

#### Python module code

from import_framework import AbstractLoader, AbstractLoaderFactory

class Ascii135Loader(AbstractLoader):
     def __init__(self):
         print self.__init__


class Ascii135LoaderFactory(AbstractLoaderFactory):
     def __init__(self, key):
         super(Ascii135LoaderFactory, self).__init__(key)
         print self.__init__

     def make(self):
         return Ascii135Loader()

register_this = Ascii135LoaderFactory("Ascii135")


#######################
				
I get the following error.

pure virtual method called

#########################

I have browsed the documentation and not found a clear answer.
I found the following quote on http://wiki.python.org/moin/boost.python/class
decribes my problem.


"There are several problems with the above arrangement, but the most important
one is that if you keep  the shared_ptr<U> alive longer than its corresponding
Python object, calls to the Python-overridable virtual functions will crash,
because they'll try to call through an invalid pointer."

How can I solve this problem?

Best regards,
Birgir Sigurjonsson.




DISCLAIMER:
This message contains information that may be privileged or confidential and is the property of the Roxar Group. It is intended only for the person to whom it is addressed. If you are not the intended recipient, you are not authorised to read, print, retain, copy, disseminate, distribute, or use this message or any part thereof. If you receive this message in error, please notify the sender immediately and delete all copies of this message. 



More information about the Cplusplus-sig mailing list