Note that there are some explanatory texts on larger screens.

plurals
  1. POExtending a virtual C++ class exposed via Boost.Python
    text
    copied!<p>I am trying to expose this C++ class using Boost.Python:</p> <pre><code>class VAlgorithm { public: VAlgorithm(const char *name); virtual ~VAlgorithm(); virtual bool Initialize() = 0; virtual bool Process() = 0; virtual bool Finalize() = 0; virtual const char *GetName() const; // Default implementation in cpp file } </code></pre> <p>My final goal is to define children of VAlgorithm in the python shell as python classes. Following <a href="http://wiki.python.org/moin/boost.python/OverridableVirtualFunctions" rel="nofollow">this example</a>, I defined a callback class:</p> <pre><code>class VAlgorithm_callback: public VAlgorithm { public: VAlgorithm_callback(PyObject *p, const char *name) : self(p), VAlgorithm(name) { } const char * GetName() const { return call_method&lt;const char *&gt;(self, "GetName"); } static const char * GetName_default(const VAlgorithm&amp; self_) { return self_.VAlgorithm::GetName(); } private: PyObject *self; }; </code></pre> <p>Right now I am exposing only the class itself and the GetName() method. Since it is a virtual class, I placed this code inside BOOST_PYTHON_MODULE:</p> <pre><code>class_&lt;VAlgorithm, VAlgorithm_callback, boost::noncopyable&gt;("VAlgorithm", no_init) // .def("GetName", &amp;VAlgorithm_callback::GetName_default); // </code></pre> <p>I can compile this and load the module in the python shell. Then I try to define a child class and call the GetName() default implementation defined in the C++ code:</p> <pre><code>&gt;&gt;&gt; class ConcAlg1(VAlgorithm): ... pass ... &gt;&gt;&gt; c1 = ConcAlg1("c1") Traceback (most recent call last): File "&lt;stdin&gt;", line 1, in &lt;module&gt; RuntimeError: This class cannot be instantiated from Python &gt;&gt;&gt; class ConcAlg2(VAlgorithm): ... def __init__(self, name): ... pass ... &gt;&gt;&gt; c2 = ConcAlg2("c2") &gt;&gt;&gt; c2.GetName() Traceback (most recent call last): File "&lt;stdin&gt;", line 1, in &lt;module&gt; Boost.Python.ArgumentError: Python argument types in VAlgorithm.GetName(ConcAlg2) did not match C++ signature: GetName(VAlgorithm) &gt;&gt;&gt; class ConcAlg3(VAlgorithm): ... def __init__(self, name): ... super(ConcAlg3, self).__init__(self, name) ... &gt;&gt;&gt; c3 = ConcAlg3("c3") Traceback (most recent call last): File "&lt;stdin&gt;", line 1, in &lt;module&gt; File "&lt;stdin&gt;", line 3, in __init__ RuntimeError: This class cannot be instantiated from Python </code></pre> <p>I am not an expert (just facing these issues for the first time), but it seems to me that ConcAlg1 and ConcAlg3 try to instantiate a VAlgorithm object and fail because of the no_init parameter used when exposing VAlgorithm (I Can't omit it or the code won't compile), and ConcAlg2 can't call GetName() because somehow it is not recognized as a child of VAlgorithm. I must be doing something trivially wrong but I can't figure out what (I am a novice of Boost.Python and extension). Can anyone please help me? Thanks</p>
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload