I've correct the pyrex code<br><br>-------- funcs.pyx --------<br>cdef extern from "c_funcs.h":<br> int callFoo(int(*)(int), int)<br> int callBar(int(*)(int*), int*)<br> char* callFooBar(char*(*)(char*), char*)<br>
<br>cdef class funcs:<br> cdef object funcsDict<br> def __init__(self):<br> cdef unsigned long fooPointer<br> fooPointer = <unsigned long>&callFoo<br> self.funcsDict = {}<br> self.funcsDict['returnFoo'] = fooPointer<br>
<br> def pyCallFoo(self, foo):<br> cdef unsigned long tmp<br> tmp = self.funcsDict['returnFoo']<br> return callFoo(<int(*)(int)>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 <<a href="mailto:robertwb@math.washington.edu">robertwb@math.washington.edu</a>>:</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'm trying to wrap a C function that requires a C function pointer as argument. I'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 <c_funcs.h><br>
<br>
int returnFoo(int foo){<br>
return foo;<br>
}<br>
<br>
int returnBar(int* bar){<br>
if (bar)<br>
return *bar;<br>
}<br>
<br>
char* returnFooBar(char* fooBar){<br>
if (fooBar)<br>
return fooBar;<br>
}<br>
<br>
int callFoo(int(*func)(int), int foo){<br>
return (*func)(foo);<br>
}<br>
<br>
int callBar(int(*func)(int*), int* bar){<br>
return (*func)(bar);<br>
}<br>
<br>
char* callFooBar(char*(*func)(char*), char* FooBar){<br>
return (*func)(FooBar);<br>
}<br>
<br>
------- funcs.pyx ----------<br>
cdef extern from "c_funcs.h":<br>
int callFoo(int(*)(int), int)<br>
int callBar(int(*)(int*), int*)<br>
char* callFooBar(char*(*)(char*), char*)<br>
<br>
cdef class funcs:<br>
cdef object funcsDict<br>
def __init__(self):<br>
cdef unsigned long fooPointer<br>
fooPointer = <unsigned long>&callFoo<br>
self.funcsDict = {}<br>
self.funcsDict['returnFoo'] = fooPointer<br>
# 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;">
print self.funcsDict['returnFoo']<br>
<br>
def pyCallFoo(self, foo):<br>
# The call to C function produces a Segmentatio Fault<br>
return callFoo(<int(*)(int)>self.funcsDict['returnFoo'], foo)<br>
</blockquote>
<br></span>
self.funcsDict['returnFoo'] 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>
return callFoo(<int(*)(int)><long>self.funcsDict['returnFoo'], foo)<br>
<br>
to force it to unpack the Python long. With in Pyrex you need an extra variable<br>
<br>
cdef long my_temp_var<br>
my_temp_var = self.funcsDict['returnFoo']<br>
return callFoo(<int(*)(int)>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>