AW: [C++-sig] Wrapping opaque pointers returned from API function s

Gottfried.Ganssauge at HAUFE.DE Gottfried.Ganssauge at HAUFE.DE
Fri Jan 10 14:58:07 CET 2003


... 
> Obviously, wrapping opaque pointers is a common thing to want to do,
> and the library should provide a better facility for it.
I made one up for my own use, see below.
This reduces my sample to

# include "pointer_converter.h"
# include <boost/python/def.hpp>
# include <boost/python/module.hpp>
# include <boost/python/return_by_value.hpp>
# include <boost/python/return_value_policy.hpp>

using namespace boost::python;

# include <iostream>

typedef struct workspace_ *workspace;

workspace osr_init (const char *) { return ((workspace) 0x47110815); }
void osr_exit (workspace ws) { std::cerr << ws << std::endl; }

BOOST_BROKEN_COMPILER_TYPE_TRAITS_SPECIALIZATION(workspace_)
DEFINE_POINTER_CONVERTER(workspace)

BOOST_PYTHON_MODULE(_pyOSR)
{
    REGISTER_POINTER_CONVERTER(workspace);

    def ("osr_init", &::osr_init, return_value_policy<return_by_value>());
    def ("osr_exit", &::osr_exit);
}

I'm not really content with the macro implementation but couldn't see
another implementation easily.

Cheers,

Gottfried

-------------><-----------------------><------------------------><----------
----------><-------------
/*
 * file: pointer_converter.h
 * date: 2003-01-10
 * Copyright C 2003 Haufe Mediengruppe
 *
 * Generic Conversion of opaque C++-pointers to a Python-
 * Wrapper.
 *
 * $Id$
 */
# include <boost/python/lvalue_from_pytype.hpp>
# include <boost/python/pointee.hpp>
# include <boost/python/to_python_converter.hpp>

/**
 * Declare a converter which will convert a C++-Pointer to an
 * opaque structure to a Python object containing the pointer
 * and vice versa.
 *
 * @param P
 * Pointer type to wrap
 *
 * @note
 * In addition you need to define specializations for type_traits
 * using BOOST_BROKEN_COMPILER_TYPE_TRAITS_SPECIALIZATION
 * 
 * @see type_traits documentation
 */
# define DEFINE_POINTER_CONVERTER(P)                              \
namespace {                                                       \
    template <class Pointer>                                      \
    struct pointer_converter                                      \
        : PyObject,                                               \
          to_python_converter<                                    \
            typename Pointer, pointer_converter<Pointer> >        \
    {                                                             \
                                                                  \
        pointer_converter() {                                     \
            lvalue_from_pytype<                                   \
                pointer_converter, &pointer_converter::type>();   \
        }                                                         \
                                                                  \
        static PyObject* convert(Pointer x) {                     \
            pointer_converter *o =                                \
                PyObject_New (                                    \
                    pointer_converter, &pointer_converter::type); \
                                                                  \
            o->x = x;                                             \
            return ((PyObject*) o);                               \
        }                                                         \
                                                                  \
        static boost::python::pointee<Pointer>::type &execute (   \
            pointer_converter<Pointer> &p_) {                     \
            return *p_.x;                                         \
        }                                                         \
                                                                  \
        static void dealloc(PyObject* self) {                     \
            PyObject_Del(self);                                   \
        }                                                         \
    private:                                                      \
        typename Pointer x;                                       \
        static PyTypeObject type;                                 \
    };                                                            \
                                                                  \
    PyTypeObject pointer_converter<P>::type = {                   \
        PyObject_HEAD_INIT(NULL)                                  \
        0,                                                        \
        # P,                                                      \
        sizeof(pointer_converter<P>),                             \
        0,                                                        \
        pointer_converter<P>::dealloc                             \
    };                                                            \
}

/**
 * register a pointer converter with the boost.python
 * converter registry.
 * This needs to go into the <module>_init function.
 *
 * @param P
 * Pointer type wrapped by a pointer converter with
 * DEFINE_POINTER_CONVERTER.
 *
 * @see DEFINE_POINTER_CONVERTER
 */
# define REGISTER_POINTER_CONVERTER(P)  pointer_converter<P>()
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.python.org/pipermail/cplusplus-sig/attachments/20030110/7bed1b93/attachment.htm>


More information about the Cplusplus-sig mailing list