views:

121

answers:

1

Hello, I followed the "official" tutorial and others but still don't manage to expose this pure virtual method (getPeptide) :

ms_mascotresults.hpp

class ms_mascotresults {
        public:

        ms_mascotresults(ms_mascotresfile  &resfile,
                         const unsigned int flags,
                         double             minProbability,
                         int                maxHitsToReport,
                         const char *       unigeneIndexFile,
                         const char *       singleHit = 0);
        ...

        virtual ms_peptide getPeptide(const int q, const int p) const = 0;
}

ms_mascotresults.cpp

#include <boost/python.hpp>
using namespace boost::python;
#include "msparser.hpp" // which includes "ms_mascotresults.hpp"
using namespace matrix_science;
#include <iostream>
#include <sstream>

struct ms_mascotresults_wrapper : ms_mascotresults, wrapper<ms_mascotresults> {
    ms_peptide getPeptide(const int q, const int p) {
        this->get_override("getPeptide")(q);
        this->get_override("getPeptide")(p);
    }
};

BOOST_PYTHON_MODULE(ms_mascotresults)
{
    class_<ms_mascotresults_wrapper, boost::noncopyable>("ms_mascotresults")
        .def("getPeptide", pure_virtual(&ms_mascotresults::getPeptide) )
    ;
}

Here are the bjam's errors :

/usr/local/boost_1_42_0/boost/python/object/value_holder.hpp:66: error: cannot declare field ‘boost::python::objects::value_holder<ms_mascotresults_wrapper>::m_held’ to be of abstract type ‘ms_mascotresults_wrapper’
ms_mascotresults.cpp:12: note:   because the following virtual functions are pure within ‘ms_mascotresults_wrapper’:
...
include/ms_mascotresults.hpp:334: note:     virtual matrix_science::ms_peptide matrix_science::ms_mascotresults::getPeptide(int, int) const
ms_mascotresults.cpp: In constructor ‘ms_mascotresults_wrapper::ms_mascotresults_wrapper()’:
ms_mascotresults.cpp:12: error: no matching function for call to ‘matrix_science::ms_mascotresults::ms_mascotresults()’
include/ms_mascotresults.hpp:284: note: candidates are: matrix_science::ms_mascotresults::ms_mascotresults(matrix_science::ms_mascotresfile&, unsigned int, double, int, const char*, const char*)
include/ms_mascotresults.hpp:109: note:                 matrix_science::ms_mascotresults::ms_mascotresults(const matrix_science::ms_mascotresults&)
...
/usr/local/boost_1_42_0/boost/python/object/value_holder.hpp: In constructor ‘boost::python::objects::value_holder<Value>::value_holder(PyObject*) [with Value = ms_mascotresults_wrapper]’:
/usr/local/boost_1_42_0/boost/python/object/value_holder.hpp:137: note: synthesized method ‘ms_mascotresults_wrapper::ms_mascotresults_wrapper()’ first required here 
/usr/local/boost_1_42_0/boost/python/object/value_holder.hpp:137: error: cannot allocate an object of abstract type ‘ms_mascotresults_wrapper’
ms_mascotresults.cpp:12: note:   since type ‘ms_mascotresults_wrapper’ has pure virtual functions

So I tried to change the constructor's signature by :

BOOST_PYTHON_MODULE(ms_mascotresults)
    {
    //class_<ms_mascotresults_wrapper, boost::noncopyable>("ms_mascotresults")
        class_<ms_mascotresults_wrapper, boost::noncopyable>("ms_mascotresults", init<ms_mascotresfile  &, const unsigned int, double, int, const char *,const char *>())
            .def("getPeptide", pure_virtual(&ms_mascotresults::getPeptide) )

Giving these errors :

/usr/local/boost_1_42_0/boost/python/object/value_holder.hpp:66: error: cannot declare field ‘boost::python::objects::value_holder<ms_mascotresults_wrapper>::m_held’ to be of abstract type ‘ms_mascotresults_wrapper’
ms_mascotresults.cpp:12: note:   because the following virtual functions are pure within ‘ms_mascotresults_wrapper’:
include/ms_mascotresults.hpp:334: note:     virtual matrix_science::ms_peptide matrix_science::ms_mascotresults::getPeptide(int, int) const
...
ms_mascotresults.cpp:24:   instantiated from here
/usr/local/boost_1_42_0/boost/python/object/value_holder.hpp:137: error: no matching function for call to ‘ms_mascotresults_wrapper::ms_mascotresults_wrapper(matrix_science::ms_mascotresfile&, const unsigned int&, const double&, const int&, const char* const&, const char* const&)’
ms_mascotresults.cpp:12: note: candidates are: ms_mascotresults_wrapper::ms_mascotresults_wrapper(const ms_mascotresults_wrapper&)
ms_mascotresults.cpp:12: note:                 ms_mascotresults_wrapper::ms_mascotresults_wrapper()

If I comment the virtual function getPeptide in the .hpp, it builds perfectly with this constructor :

        class_<ms_mascotresults>("ms_mascotresults", init<ms_mascotresfile  &, const unsigned int, double, int, const char *,const char *>() )

So I'm a bit lost...

A: 

I think your wrapper function needs to be const - at the moment it isn't overriding the pure virtual version in the base class which is const.

struct ms_mascotresults_wrapper : ms_mascotresults, wrapper<ms_mascotresults> {
    ms_peptide getPeptide(const int q, const int p) const {
        this->get_override("getPeptide")(q);
        this->get_override("getPeptide")(p);
    }
};

Also note that get_override might return NULL, so you should probably test what it returns before calling it.

Autopulated