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

Gottfried.Ganssauge at HAUFE.DE Gottfried.Ganssauge at HAUFE.DE
Mon Jan 13 09:44:43 CET 2003


...
> >> namespace detail
> >                      ^^^^^
> > Both mscv compilers (6.0 and 7) agree that this is ambigous 
> (probably with
> > boost::python::detail !?). The complaint, alas, occurs when using
> > detail::dealloc!
> 
> You must have a using directive lying around somewhere, or you put
> all of this into boost::python, which I didn't expect.  Anyway, we can
You are right:
I had "using namespace boost::python" after the #include for
pointer_converter.h.

> pick a different name.  There is probably a dealloc in
> boost::python::detail already.
Nope.

> 
> >> {
> >>     extern "C" inline void dealloc(PyObject* self)
> >                        ^^^^^
> > We're using a pointer to this function; therefore this 
> function can't be
> > expanded inline, right?
ok.

> 
> Right; the inline declaration just prevents the linker from seeing
> multiple definitions.
> 
...
> >>     // This is a POD so we can use PyObject_Del on it, for example.
> 
> > I see your point, but msvc doesn't accept your upcast below; 
> 
> I didn't say I tested the code ;-)
Of course.
Anyway, your upcast is probably invalid anyway, because PyObject ist not a
base class of instance.
> 
> > and anyway; who guarantees that PyObject won't be declared
> > differently in the next python release?
> 
> Guido does.
> 
> > What about struct instance : public PyObject { Pointer x; }; ?
> 
> No, that's non-POD.  It has a base class.  
I think I have a solution that is hopefully more conforming but doesn't rely
on the Python implementation details (and it even resembles a bit to real
inheritance)
	struct instance {
		PyObject base_;
		Pointer x;
	};
...
	static PyObject* convert(Pointer x)
	{
		instance *o = PyObject_New (instance, &type_object);
		o->x = x;
		return &o->base_;
	}
I can't lookup the paragraph in the standard, but I found something in the
draft of "C++ in a nutshell".
In Chapter 7 it says:
"""
A POD class can contain padding between data members, but no padding appears
before the first member. Therefore, a pointer to the POD object can be
converted (with reinterpret_cast<>) to a pointer to the first element.
"""

My next draft follows below

Cheers,

Gottfried
-----------><------------------------><-----------------------><------------
---------><--------------
# ifndef pointer_converter_h_
# define pointer_convert_h_
# include <boost/python/lvalue_from_pytype.hpp>
# include <boost/python/to_python_converter.hpp>

// convert_opaque_pointer --
//
// usage: convert_opaque_pointer<pointer_type>("name")
//
// registers to- and from- python conversions for a type pointer_type,
// and a corresponding Python type called "name".
//
// Note:
// In addition you may need to define specializations for type_traits
// on the base class of pointer_type using
// BOOST_BROKEN_COMPILER_TYPE_TRAITS_SPECIALIZATION
//
namespace opc_detail
{
    extern "C" inline void dealloc(PyObject* self)
    {
        PyObject_Del(self);
    }
}

template <class Pointer>
struct convert_opaque_pointer
    : ::boost::python::to_python_converter<
          Pointer, convert_opaque_pointer<Pointer> >
{
    // This is a POD so we can use PyObject_Del on it, for example.
    struct instance
    {
        PyObject base_;
        Pointer x;
    };

    convert_opaque_pointer(char const* name)
    {
        type_object.tp_name = const_cast<char *> (name);

        boost::python::lvalue_from_pytype<
            convert_opaque_pointer<Pointer>,
			&convert_opaque_pointer<Pointer>::type_object
        >();
    }

    static PyObject* convert(Pointer x)
    {
        instance *o = PyObject_New (instance, &type_object);

        o->x = x;
        return &o->base_;
    }

    static typename boost::remove_pointer<Pointer>::type&
    execute(instance &p_)
    {
        return *p_.x;
    }

    static PyTypeObject type_object;
};

template <class Pointer>
PyTypeObject convert_opaque_pointer<Pointer>::type_object =
{
    PyObject_HEAD_INIT(NULL)
    0,
    0,
    sizeof(typename convert_opaque_pointer<Pointer>::instance),
    0,
    opc_detail::dealloc
};
# endif	// pointer_convert_h_
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.python.org/pipermail/cplusplus-sig/attachments/20030113/7865b489/attachment.htm>


More information about the Cplusplus-sig mailing list