<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2//EN">
<HTML>
<HEAD>
<META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=US-ASCII">
<META NAME="Generator" CONTENT="MS Exchange Server version 5.5.2653.12">
<TITLE>AW: AW: [C++-sig] Wrapping opaque pointers returned from API function s</TITLE>
</HEAD>
<BODY>
<BR>
<BR>

<P><FONT SIZE=2>&gt; -----Ursprungliche Nachricht-----</FONT>
<BR><FONT SIZE=2>&gt; Von: David Abrahams [<A HREF="mailto:dave@boost-consulting.com">mailto:dave@boost-consulting.com</A>]</FONT>
<BR><FONT SIZE=2>&gt; Gesendet: Montag, 13. Januar 2003 13:47</FONT>
<BR><FONT SIZE=2>&gt; An: c++-sig@python.org</FONT>
<BR><FONT SIZE=2>&gt; Betreff: Re: AW: [C++-sig] Wrapping opaque pointers returned from API</FONT>
<BR><FONT SIZE=2>&gt; function s</FONT>
<BR><FONT SIZE=2>&gt; </FONT>
<BR><FONT SIZE=2>&gt; </FONT>
<BR><FONT SIZE=2>&gt; Gottfried.Ganssauge@HAUFE.DE writes:</FONT>
<BR><FONT SIZE=2>&gt; </FONT>
<BR><FONT SIZE=2>&gt; &gt;&gt; I didn't say I tested the code ;-)</FONT>
<BR><FONT SIZE=2>&gt; &gt;</FONT>
<BR><FONT SIZE=2>&gt; &gt; Of course.</FONT>
<BR><FONT SIZE=2>&gt; &gt; Anyway, your upcast is probably invalid anyway, because </FONT>
<BR><FONT SIZE=2>&gt; PyObject ist not a</FONT>
<BR><FONT SIZE=2>&gt; &gt; base class of instance.</FONT>
<BR><FONT SIZE=2>&gt; </FONT>
<BR><FONT SIZE=2>&gt; No, it is not invalid.&nbsp; My upcast template is specially designed to</FONT>
<BR><FONT SIZE=2>&gt; deal with this.&nbsp; Please try doing as I suggested.</FONT>
<BR><FONT SIZE=2>Here you are:</FONT>
<BR><FONT SIZE=2>c:\daten\devel\boost\boost\python\cast.hpp(31) : error C2039: 'type' : Ist kein Element von 'base_type_traits&lt;struct convert_opaque_pointer&lt;struct workspace_ *&gt;::instance&gt;'</FONT></P>

<P><FONT SIZE=2>c:\daten\devel\boost\boost\python\cast.hpp(52) : Siehe Verweis auf Instantiierung der kompilierten Funktionsvorlage 'struct _object *__cdecl boost::python::detail::upcast(struct convert_opaque_pointer&lt;struct workspace_ *&gt;::instance *,int *,int *,struct _object *)'</FONT></P>

<P><FONT SIZE=2>I had seen that message before and concluded from it, that convert_opaque_pointer&lt;struct workspace_ *&gt;::instance * can't be converted to PyObject * using upcast&lt;&gt;.</FONT></P>

<P><FONT SIZE=2>&gt; </FONT>
<BR><FONT SIZE=2>&gt; &gt;&gt; No, that's non-POD.&nbsp; It has a base class.&nbsp; </FONT>
<BR><FONT SIZE=2>&gt; &gt;</FONT>
<BR><FONT SIZE=2>&gt; &gt; I think I have a solution that is hopefully more conforming </FONT>
<BR><FONT SIZE=2>&gt; but doesn't rely</FONT>
<BR><FONT SIZE=2>&gt; &gt; on the Python implementation details (and it even resembles </FONT>
<BR><FONT SIZE=2>&gt; a bit to real</FONT>
<BR><FONT SIZE=2>&gt; &gt; inheritance)</FONT>
<BR><FONT SIZE=2>&gt; &gt; &nbsp;&nbsp;&nbsp; struct instance {</FONT>
<BR><FONT SIZE=2>&gt; &gt; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; PyObject base_;</FONT>
<BR><FONT SIZE=2>&gt; &gt; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Pointer x;</FONT>
<BR><FONT SIZE=2>&gt; &gt; &nbsp;&nbsp;&nbsp; };</FONT>
<BR><FONT SIZE=2>&gt; </FONT>
<BR><FONT SIZE=2>&gt; The contents of PyObject are still Python implementation details.</FONT>
<BR><FONT SIZE=2>True, but I don't use it. PyObject_HEAD may be the implementation of PyObject but there is no direct relationship between the two except Guido. (no criticism; just a fact)</FONT></P>

<P><FONT SIZE=2>&gt; This one is no better than my proposal, and may in fact take extra</FONT>
<BR><FONT SIZE=2>&gt; storage for alignment.</FONT>
<BR><FONT SIZE=2>At least it doesn't need a cast :-)</FONT>
<BR><FONT SIZE=2>Why should there be extra alignment storage used after PyObject but not after PyObject_HEAD?</FONT>
</P>

<P><FONT SIZE=2>&gt; </FONT>
<BR><FONT SIZE=2>&gt; &gt; &nbsp;&nbsp;&nbsp; static PyObject* convert(Pointer x)</FONT>
<BR><FONT SIZE=2>&gt; &gt; &nbsp;&nbsp;&nbsp; {</FONT>
<BR><FONT SIZE=2>&gt; &gt; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; instance *o = PyObject_New (instance, &amp;type_object);</FONT>
<BR><FONT SIZE=2>&gt; &gt; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; o-&gt;x = x;</FONT>
<BR><FONT SIZE=2>&gt; &gt; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return &amp;o-&gt;base_;</FONT>
<BR><FONT SIZE=2>&gt; &gt; &nbsp;&nbsp;&nbsp; }</FONT>
<BR><FONT SIZE=2>&gt; &gt; I can't lookup the paragraph in the standard, but I found </FONT>
<BR><FONT SIZE=2>&gt; something in the</FONT>
<BR><FONT SIZE=2>&gt; &gt; draft of &quot;C++ in a nutshell&quot;.</FONT>
<BR><FONT SIZE=2>&gt; &gt; In Chapter 7 it says:</FONT>
<BR><FONT SIZE=2>&gt; &gt; &quot;&quot;&quot;</FONT>
<BR><FONT SIZE=2>&gt; &gt; A POD class can contain padding between data members, but </FONT>
<BR><FONT SIZE=2>&gt; no padding appears</FONT>
<BR><FONT SIZE=2>&gt; &gt; before the first member. Therefore, a pointer to the POD </FONT>
<BR><FONT SIZE=2>&gt; object can be</FONT>
<BR><FONT SIZE=2>&gt; &gt; converted (with reinterpret_cast&lt;&gt;) to a pointer to the </FONT>
<BR><FONT SIZE=2>&gt; first element.</FONT>
<BR><FONT SIZE=2>&gt; &gt; &quot;&quot;&quot;</FONT>
<BR><FONT SIZE=2>&gt; </FONT>
<BR><FONT SIZE=2>&gt; They're wrong about reinterpret_cast&lt;&gt;, as far as the standard goes.</FONT>
<BR><FONT SIZE=2>&gt; That performs an implementation-defined mapping.&nbsp; The only thing you</FONT>
<BR><FONT SIZE=2>&gt; can do portably with it is convert a pointer to a different type and</FONT>
<BR><FONT SIZE=2>&gt; back again, without using it in between.&nbsp; Please, just try it the way</FONT>
<BR><FONT SIZE=2>&gt; I suggested!</FONT>
<BR><FONT SIZE=2>My solution only uses the fact, that there is no extra padding before the base_ member so that a pointer to base_ may be returned from the convert method that can be converted back to a pointer to our instance struct.</FONT></P>

<P><FONT SIZE=2>Cheers,</FONT>
</P>

<P><FONT SIZE=2>Gottfried</FONT>
</P>

</BODY>
</HTML>