[SciPy-user] C/Fortran callbacks [was "integrate.odeint"]

Pearu Peterson pearu at scipy.org
Sun Oct 17 17:12:06 CDT 2004

On Sun, 17 Oct 2004, Robert Kern wrote:

> Travis Oliphant wrote:
>> We have been interested in something like this for a while.    I would like 
>> to see the user be able to write c and/or fortran code to compute the 
>> function to be integrated.
> How about this for a sketch:
> C or Fortran function bodies can be defined as a Python string a la weave.
>  C: We use the weave framework to make an extension module with the function 
> body embedded into a properly defined function.
>  Fortran: The Fortran code will be put into a separate Fortran file as a 
> subroutine. A C extension module is written out which will reference the 
> subroutine.
> The extension module will create a CObject which contains a direct function 
> pointer to the function.
> f2py could be modified (I hope) to accept one of these CObjects as an valid 
> input for a callback.
> An additional nicety would be for f2py to (either optionally or additionally) 
> provide these CObjects for any subroutine wrapped by f2py. That way, one 
> could write a single Fortran file (with helpful "cf2py" comments) with all of 
> one's callbacks instead of semi-inline weave code*. In fact, if this 
> modification is made to f2py, then both the C and Fortran can use it as the 
> back end for generating the extension module which holds the user-defined 
> callback.
> Pearu, do you have any feelings about the feasibility of this sketch?

Check out the latest f2py from CVS:

Now every fortran object that represents some C or Fortran function, has 
attribute `_cpointer` that is of PyCObject type. F2py generated wrappers 
accept PyCObject arguments as call-back arguments and assume that such 
PyCObject arguments contain pointers to C or Fortran functions.

Note that f2py cannot check if PyCObject arguments are valid in any way to 
be passed on as an call-back argument. So, if the signatures of the given
and expected callback arguments are slightly different, it will most 
probably cause a Python crash.

See an example at the end of this message.

This is a very new feature in f2py and so needs more testing before using
in production codes. Let me know if you experience any trouble or success 
with this feature.


!File cb.f
       subroutine foo(bar)
       external bar
       integer x
!f2py intent(out) x
       call bar(x)

       subroutine cb(x)
       integer x
!f2py intent(out) x
       x = 156

$ f2py -m m cb.f -c

In [1]: from m import foo,cb

In [2]: foo(lambda:2)
  x= 2

In [3]: cb()
Out[3]: 156

In [4]: foo(cb)
  x= 156

In [5]: cb._cpointer
Out[5]: <PyCObject object at 0x401a3d58>

In [6]: foo(cb._cpointer)
  x= 156

More information about the SciPy-user mailing list