[C++-sig] [boost.python] Can't import a wrapped template class

Paul O. Seidon p.oseidon at datec.at
Fri Oct 26 20:24:33 CEST 2012


Paul O.  Seidon wrote:

> Stefan Seefeld wrote:
> 
>> On 10/26/2012 01:50 PM, Paul O. Seidon wrote:
>>> The ctor is decl'ed in varbls.h as
>>>
>>> _Variable();
>>>
>>> and it's def'ed in varbls.cpp like so:
>>>
>>> template <typename TYPE>
>>> _Variable<TYPE>::_Variable()
>>> : _value( 0)
>>> {
>>>      //ctor
>>> }
>> 
>> That doesn't work. When the compiler compiles varbls.cpp, it doesn't
>> know what types to instantiate the _Variable template for, so you need
>> to either explicitly instantiate it for all the types you use in your
>> module, or keep the definitions in the varbls.h header so the compiler
>> can implicitly instantiate them when compiling the Python module.
>> 
>>     Stefan
>> 
> 
> That didn't make any difference. And it would have surprised me, if it
> did: varbls.h contains the declaration, varbls.cpp contains the
> definition, the wrapper is in main.cpp. So if the compiler sees any need
> to include sometihng, it will and the linker will link the definition.
> 
> But you certainly are right, the symbol is in the .so-file but the symbol
> isn't resolved by the linker. Hm, but where should I instantiate the
> class? I thought
> 
> BOOST_PYTHON_MODULE(_varbls)
> {
> 
>      class_<VariableDouble>("VariableDouble")
>          .def( init<>())
>          .def( init<const double&>())
>      ;
> }
> 
> would do that. Should I try
> 
> dont_care = _Variable<double>();
> 
> in main.cpp? Looks a bit strange, but would force the compiler to generate
> code for sure.
> 
> Paul


That doesn't do it either. I can't help but post the compete code here to be 
sure I'm not misunderstood. The lib consists of varbls.cpp and varbls.h and 
the wrapper main.cpp.

varbls.h
========

#ifndef VARBLS_H
#define VARBLS_H


template <class TYPE>
class _Variable
{
public:
                                _Variable();
                                _Variable( const TYPE& v);
    virtual                     ~_Variable();

    TYPE                        value() const;
    void                        value( const double& v);

protected:
private:
    TYPE                        _value;
};


/*
class VariableFloat : public _Variable<double>
{
public:
                                VariableFloat( const double& v)
                                : _Variable<double>( v)
                                {};

    virtual                     ~VariableFloat()
                                {};
};
*/


class VariableFloat
{
public:
                                VariableFloat( const double& v=0)
                                : _value( v)
                                {};

    virtual                     ~VariableFloat()
                                {};

    double                      value() const
                                {   return _value;
                                };

    void                        value( const double& v)
                                {   _value = v;
                                };

private:
    double                      _value;
};


#endif // VARBLS_H


varbls.cpp
==========

#include "varbls.h"


template <typename TYPE>
_Variable<TYPE>::_Variable()
: _value( 0)
{
    //ctor
}


template <typename TYPE>
_Variable<TYPE>::_Variable( const TYPE& v)
: _value( v)
{
    //ctor
}


template <typename TYPE>
_Variable<TYPE>::~_Variable()
{
    //dtor
}


template <typename TYPE> TYPE _Variable<TYPE>::value() const
{
    return _value;
}


template <typename TYPE> void _Variable<TYPE>::value( const double& v)
{
    _value = v;
}


main.cpp
========

#include <Python.h>
#include <boost/python.hpp>
using namespace boost::python;

#include "./src/varbls.h"


#include <string>
using namespace std;


typedef _Variable<double>  VariableDouble;

/*
void    (VariableFloat::*value_1)( const double& ) = &VariableFloat::value;
double  (VariableFloat::*value_2)() const = &VariableFloat::value;
*/

BOOST_PYTHON_MODULE(_varbls)
{

    class_<VariableDouble>("VariableDouble")
        .def( init<>())
        .def( init<const double&>())
    ;

/*
    class_<VariableFloat>("VariableFloat")
        .def( init<>())
        .def( init<const double&>())
        .def( "value", value_1)
        .def( "value", value_2)
    ;
*/
}

VariableDouble  _DONT_CARE = VariableDouble();



Paul




More information about the Cplusplus-sig mailing list