I&#39;ve correct the pyrex code<br><br>-------- funcs.pyx --------<br>cdef extern from &quot;c_funcs.h&quot;:<br>&nbsp; int callFoo(int(*)(int), int)<br>&nbsp; int callBar(int(*)(int*), int*)<br>&nbsp; char* callFooBar(char*(*)(char*), char*)<br>
<br>cdef class funcs:<br>&nbsp; cdef object funcsDict<br>&nbsp; def __init__(self):<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; cdef unsigned long fooPointer<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; fooPointer = &lt;unsigned long&gt;&amp;callFoo<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; self.funcsDict = {}<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; self.funcsDict[&#39;returnFoo&#39;] = fooPointer<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <br>&nbsp; def pyCallFoo(self, foo):<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; cdef unsigned long tmp<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; tmp = self.funcsDict[&#39;returnFoo&#39;]<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return callFoo(&lt;int(*)(int)&gt;tmp, foo)<br><br><br>But it gives me a segmentation fault again... :(<br>
<br><br><div><span class="gmail_quote">2008/4/11, Robert Bradshaw &lt;<a href="mailto:robertwb@math.washington.edu">robertwb@math.washington.edu</a>&gt;:</span><blockquote class="gmail_quote" style="border-left: 1px solid rgb(204, 204, 204); margin: 0pt 0pt 0pt 0.8ex; padding-left: 1ex;">
<div><span class="e" id="q_1193cdf204487feb_0">On Apr 11, 2008, at 2:12 AM, Daniele Pianu wrote:<br>
<blockquote class="gmail_quote" style="border-left: 1px solid rgb(204, 204, 204); padding-left: 1ex;">
I&#39;m trying to wrap a C function that requires a C function pointer as argument. I&#39;ve wrote a pyrex extension with a dictionary where every key is a C function name, and every entry is a C function pointer, stored as a long. I call the C function from python passing the function name and the necessary data.<br>

<br>
An example:<br>
<br>
-------- c_funcs.h ---------<br>
<br>
int returnFoo(int);<br>
<br>
int returnBar(int*);<br>
<br>
char* returnFooBar(char*);<br>
<br>
int callFoo(int(*)(int), int);<br>
<br>
int callBar(int(*)(int*), int*);<br>
<br>
char* callFooBar(char*(*)(char*), char*);<br>
<br>
<br>
------- c_funcs.c -------<br>
#include &lt;c_funcs.h&gt;<br>
<br>
int returnFoo(int foo){<br>
 &nbsp;return foo;<br>
}<br>
<br>
int returnBar(int* bar){<br>
 &nbsp;if (bar)<br>
 &nbsp; &nbsp;return *bar;<br>
}<br>
<br>
char* returnFooBar(char* fooBar){<br>
 &nbsp;if (fooBar)<br>
 &nbsp; &nbsp;return fooBar;<br>
}<br>
<br>
int callFoo(int(*func)(int), int foo){<br>
 &nbsp;return (*func)(foo);<br>
}<br>
<br>
int callBar(int(*func)(int*), int* bar){<br>
 &nbsp;return (*func)(bar);<br>
}<br>
<br>
char* callFooBar(char*(*func)(char*), char* FooBar){<br>
 &nbsp;return (*func)(FooBar);<br>
}<br>
<br>
------- funcs.pyx ----------<br>
cdef extern from &quot;c_funcs.h&quot;:<br>
 &nbsp;int callFoo(int(*)(int), int)<br>
 &nbsp;int callBar(int(*)(int*), int*)<br>
 &nbsp;char* callFooBar(char*(*)(char*), char*)<br>
<br>
cdef class funcs:<br>
 &nbsp;cdef object funcsDict<br>
 &nbsp;def __init__(self):<br>
 &nbsp; &nbsp; &nbsp;cdef unsigned long fooPointer<br>
 &nbsp; &nbsp; &nbsp;fooPointer = &lt;unsigned long&gt;&amp;callFoo<br>
 &nbsp; &nbsp; &nbsp;self.funcsDict = {}<br>
 &nbsp; &nbsp; &nbsp;self.funcsDict[&#39;returnFoo&#39;] = fooPointer<br>
 &nbsp; &nbsp; &nbsp;# Here the python interpreter prints an integer, not a long as expected!!!<br>
</blockquote>
<br></span></div>
Python ints are c longs, which may not actually be the size of pointers on all systems.<span class="q"><br>
<br>
<blockquote class="gmail_quote" style="border-left: 1px solid rgb(204, 204, 204); padding-left: 1ex;">
 &nbsp; &nbsp; &nbsp;print self.funcsDict[&#39;returnFoo&#39;]<br>
<br>
 &nbsp;def pyCallFoo(self, foo):<br>
 &nbsp; &nbsp; &nbsp;# The call to C function produces a Segmentatio Fault<br>
 &nbsp; &nbsp; &nbsp;return callFoo(&lt;int(*)(int)&gt;self.funcsDict[&#39;returnFoo&#39;], foo)<br>
</blockquote>
<br></span>
self.funcsDict[&#39;returnFoo&#39;] returns a PyObject* (that points to a Python int), and it is the memory location of the object that you are casting to an int(*)(int).<br>
<br>
In Cython you can write<br>
<br>
 &nbsp; &nbsp;return callFoo(&lt;int(*)(int)&gt;&lt;long&gt;self.funcsDict[&#39;returnFoo&#39;], foo)<br>
<br>
to force it to unpack the Python long. With in Pyrex you need an extra variable<br>
<br>
 &nbsp; &nbsp;cdef long my_temp_var<br>
 &nbsp; &nbsp;my_temp_var = self.funcsDict[&#39;returnFoo&#39;]<br>
 &nbsp; &nbsp;return callFoo(&lt;int(*)(int)&gt;my_temp_var, foo)<br>
<br>
Just make sure no one messes with your dictionary!<div><span class="e" id="q_1193cdf204487feb_4"><br>
<br>
<blockquote class="gmail_quote" style="border-left: 1px solid rgb(204, 204, 204); padding-left: 1ex;">
<br>
<br>
How can I solve the problem? Every advice about alternative implementation is also appreciated :)<br>
</blockquote>
<br>
<br>
<br>
</span></div></blockquote></div><br>