<div><span class="gmail_quote">On 10/17/07, <b class="gmail_sendername">Michael Foord</b> &lt;<a onclick="return top.js.OpenExtLink(window,event,this)" href="mailto:fuzzyman@voidspace.org.uk" target="_blank">fuzzyman@voidspace.org.uk
</a>&gt; wrote:</span> 
<blockquote class="gmail_quote" style="PADDING-LEFT: 1ex; MARGIN: 0px 0px 0px 0.8ex; BORDER-LEFT: #ccc 1px solid">I would be sad if we chose any approach that couldn&#39;t work on Mono. :-(</blockquote>
<div>&nbsp;</div>
<div>I agree.&nbsp; Assuming this rules out MC++, I think the next best approach is (as Paolo suggests) to try to shift as much of the work to C# as possible.</div>
<div>&nbsp;</div>
<div>Here&#39;s an architecture to think about. Consider the following example for PySequence_Length:</div>
<div>&nbsp;</div>
<div>In C:</div>
<div><font face="courier new,monospace">typedef int (__stdcall *PFN_iO)(PyObject *);</font></div>
<div><font face="courier new,monospace">PFN_iO PFN_PySequence_Length;</font></div>
<div><font face="courier new,monospace">void Set_PySequence_Length(PFN_iO callback)<br>{<br>&nbsp;&nbsp;&nbsp; PFN_PySequence_Length = callback;<br>}<br>int PySequence_Length(PyObject * object)<br>{<br>&nbsp;&nbsp;&nbsp; return PFN_PySequence_Length(object);
<br>}<br></font></div>
<div>In C#:</div>
<div><font face="courier new,monospace">public delegate int PFN_iO(IntPtr object);</font></div>
<div><font face="courier new,monospace"></font>&nbsp;</div>
<div><font face="courier new,monospace">[DllImport(&quot;extension.DLL&quot;)]<br>public static extern void Set_PySequence_Length(PFN_iO callback);<br></font></div>
<div><font face="courier new,monospace">public static&nbsp;int PySequence_Length(IntPtr obj_in)</font></div>
<div><font face="courier new,monospace">{</font></div>
<div><font face="courier new,monospace">&nbsp;&nbsp;&nbsp; object o = ObjectConverter(obj_in);</font></div>
<div><font face="courier new,monospace">&nbsp;&nbsp;&nbsp; // Do something with o</font></div>
<div><font face="courier new,monospace">&nbsp;&nbsp;&nbsp; return result;</font></div>
<div><font face="courier new,monospace">}</font></div>
<div><font face="courier new,monospace"></font>&nbsp;</div>
<div><font face="courier new,monospace">public static void SetApiFunctionsAtStartup()</font></div>
<div><font face="courier new,monospace">{</font></div>
<div><font face="courier new,monospace">&nbsp;&nbsp;&nbsp; Set_PySequence_Length(PySequence_Length);</font></div>
<div><font face="courier new,monospace">}</font></div>
<div>&nbsp;</div>
<div>Ignoring exception-handling for now, the idea is to keep most of the implementation in C# and to have the C# code register callback functions as actual implementations for the parts of the Python API that we&#39;re going to duplicate.
</div>
<div>&nbsp;</div>
<div>This is idea is dependent on a kind of &quot;global registry&quot; of objects with representations on both sides of the border.&nbsp; Such a registry will almost certainly be required in order to translate between the two -- if for no other reason than to handle reference-counting and/or garbage collection.&nbsp; Any PyObject being passed across the boundary would then actually be some kind of index into the registry.
</div>
<div>&nbsp;</div>
<div>A &quot;PyTuple_New&quot; would call through the delegate into C# where (say) a List&lt;object&gt; would be created and added to the registry, with its unique identifer being passed back to the C caller as a &quot;PyObject *&quot;.
</div>
<div>&nbsp;</div>
<div>INCREF and DECREF on the C side would affect a reference count in the registry. Once the DECREF takes the reference count down to zero, the object is removed.&nbsp; At that point, it may very well still be a valid CLR object in use by other parts of the program -- just not by the C extension.
</div>
<div>&nbsp;</div>
<div>Objects actually defined in the C extension would be required to use either PyObject_New or Py_NewReference as part of their initialization in order for the proper fixups to happen.</div>
<div>&nbsp;</div>
<div>&nbsp;</div>
<div>What do you think?</div>
<div>&nbsp;</div>
<div>--</div>
<div>Curt Hagenlocher</div>
<div><a href="mailto:curt@hagenlocher.org">curt@hagenlocher.org</a></div></div>