Boost logo

Boost :

From: John Hunter (jdhunter_at_[hidden])
Date: 2001-08-19 15:18:13


>>>>> "John" == John Hunter <jdhunter_at_[hidden]> writes:

    Docs> Because the to_python and from_python functions for a
    Docs> user-defined class are defined by extension_class<T>, it is
    Docs> important that an instantiation of extension_class<T> is
    Docs> visible to any code which wraps a C++ function with a T, T*,
    Docs> const T&, etc. parameter or return value. In particular, you
    Docs> may want to create all of the classes at the top of your
    Docs> module's init function, then def the member functions later
    Docs> to avoid problems with inter-class dependencies.

    John> Is this related to my problem? I certainly include the
    John> header for the 'Date' class before the module init function
    John> and VectorPy<Date> instantiation.

Ok, figured this one out; the problem described in the docs was my
problem. Because I developed my classes into different .cpp files,
there were classes and functions that were not visible to the other
code that depended on them. When I dumped everything into a single
.hpp file, all was well.

In case anyone else bumps up against the same problem, here is how I
got it working while retaining the cpp files.

In the VectorPy class, I failed to include the DatePy header; I only
included the Date header, so when I tried to instantiate VectorPy
date, the compiler complained:

  extension_class.hpp:362: no matching function for call to
         `py_extension_class_converters (boost::python::type<Date>)'

One down. The other problem was in the Date class. When I tried to
'def' functions that returned a vector<Date>, I got the error

  extension_class.hpp:362: conversion from
        `boost::python::type<vector<Date,allocator<Date> > >'
        to non-scalar type `boost::python::type<Date>' requested

This was cleared up by including the VectorPy header and then
declaring 'VectorPy<Date>' as an extern template class like so:

#include "VectorPy.h"
extern template class VectorPy<Date>;

Finally, since VectorPy has to instantiate a number of template
functions as well as the template class for each kind of std::vector
you want to wrap, a instantiation macro comes in handy:

//template instantiations
#define INSTANTIATE_TEMPLATE(T) \
template class vector<T>;\
template void v_push_back( std::vector<T>&, const T&);\
template size_t v_size( const std::vector<T>&);\
template T v_get( const std::vector<T>& , const size_t& );\
template class VectorPy<T>;

INSTANTIATE_TEMPLATE(float)
INSTANTIATE_TEMPLATE(int)
INSTANTIATE_TEMPLATE(Date)

One question I'm still pondering: since templates are supposed to be
able to replace most preprocessor macros, is it possible to use a
template instead of a macro to do these instantiations?

Regards,
John Hunter


Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk