[f2py] Unexpected text pyfunction_cptr encountered

Mark.Oberfield at noaa.gov Mark.Oberfield at noaa.gov
Sat Oct 16 20:44:07 EEST 2010


Hi Pearu,

Thank you so much for your help! 

Don't worry about the 'E'!  The 'E' is probably due to array bounds write; ASTRING is allocated 10 chars, you overflowed it.  ;)

Mark
----- Original Message -----
From: Pearu Peterson <pearu.peterson at gmail.com>
Date: Saturday, October 16, 2010 5:49 am
Subject: Re: [f2py] Unexpected text pyfunction_cptr encountered
To: For users of the f2py program <f2py-users at cens.ioc.ee>


> Hi,
> You can use the f2py intent(callback) feature to achieve what you have
> described. Here follows an example:
> 
> c foo.f
>       SUBROUTINE A()
> c     the following 2 lines say that f2py should construct the
> run_python function
> cf2py intent(callback) RUN_PYTHON
>       EXTERNAL RUN_PYTHON
>       CHARACTER*10 ASTRING
> c     the following line defines the signature for run_python function
> cf2py call run_python(astring)
>       PRINT*, "ENTERING A"
>       ASTRING = "abcdefghijklm"
>       CALL B(ASTRING)
>       PRINT*, "LEAVING A"
>       RETURN
>       END
> 
>       SUBROUTINE B(ASTRING)
> c
> c       Cannot change this routine
> c
>       CHARACTER*10 ASTRING
>       PRINT*, "ENTERING B"
>       CALL C(ASTRING)
>       PRINT*, "LEAVING B"
>       RETURN
>       END
> 
>       SUBROUTINE C(ASTRING)
>       EXTERNAL RUN_PYTHON
>       CHARACTER*10 ASTRING
>       PRINT*, "ENTERING C"
>       CALL RUN_PYTHON(ASTRING)
>       PRINT*, "LEAVING C"
>       RETURN
>       END
> c end of foo.f
> 
> Build the extension module:
> 
> f2py -c -m foo foo.f
> 
> Usage from Python:
> 
> >>> import foo
> >>> def func(string): print "entering func(%r)" % (string)
> ...
> >>> foo.a(func)
>  ENTERING A
>  ENTERING B
>  ENTERING C
> entering func('abcdefghijE')
>  LEAVING C
>  LEAVING B
>  LEAVING A
> >>> # note that function `a` takes callable argument while fortran 
> subroutine `a` defined is as external function
> >>> print(foo.a.__doc__)
> a - Function signature:
>   a(run_python,[run_python_extra_args])
> Required arguments:
>   run_python : call-back function
> Optional arguments:
>   run_python_extra_args := () input tuple
> Call-back functions:
>   def run_python(astring): return
>   Required arguments:
>     astring : input string(len=10)
> 
> 
> PS: I am not sure where the ending 'E' comes from, I'll look into it..
> 
> HTH,
> Pearu
> 
> 
> 
> On Fri, Oct 15, 2010 at 10:43 PM, Mark Oberfield
> <Mark.Oberfield at noaa.gov> wrote:
> > Hi,
> >
> > What I am attempting to do with f2py is to have a FORTRAN77 subroutine
> > call a Python function.  The f2py tutorial/documentation provides an
> > simple example of this, but what I want to do is a little more
> > elaborate and I running into problems. First, the description of the
> > puzzle.
> >
> > I have three FORTRAN routines, "A","B" & "C".  I have source code for
> > routines "A" and "C" and I can change them to accomplish my task.
> >
> > Subroutine A was originally "PROGRAM A" but now will be called from
> > Python while I pass the Python routine, 'pyfunction', that I want to
> > be executed.
> >
> > I cannot modify the B Subroutine; please consider it to be inside a
> > library for which I don't have the source code.
> >
> > Subroutine "C" is where I want to execute the Python routine. So the
> > execution stack looks something like this:
> >
> > python=>A=>B=>C=>pyfunction
> >
> > Since function names are not allowed in FORTRAN common blocks, I wrote
> > simple "C" routines to store and execute the function pointer when
> > called from FORTRAN.  I would think this would work but I get an error.
> >
> > Here are the routines:
> >
> >      SUBROUTINE A(PYFUNCTION)
> >      CHARACTER*10 ASTRING
> >      CALL RGSTR_FUNCTION(PYFUNCTION)
> >      ASTRING = ' '
> >      CALL B(ASTRING)
> >      PRINT *, ASTRING
> >      RETURN
> >      END
> >
> >      SUBROUTINE B(ASTRING)
> >      C
> >      C Cannot change this routine
> >      C
> >      CHARACTER*10 ASTRING
> >      CALL C(ASTRING)
> >      RETURN
> >      END
> >
> >      SUBROUTINE C(ASTRING)
> >      CHARACTER*10 ASTRING
> >      CALL RUN_PYTHON(ASTRING)
> >      RETURN
> >      END
> >
> > c2py.c:
> >        /*
> >         * Declare a private static variable, a function pointer 
> which is a
> >         * Python routine
> >         */
> >        static void (*python_function)(char*);
> >
> >        void rgstr_function(void *fptr)
> >        {
> >           python_function = (void(*)(char*))fptr;
> >        }
> >
> >        void run_python(char *astring)
> >        {
> >           (*python_function)(astring);
> >        }
> >
> > I build it okay:
> >
> > f2py -c --f77flags=-qextname=a:b:c -m fmodule a.f b.f c.f c2py.c
> >
> > and fmodule.so gets built.
> >
> > Python 2.7 (r27:82500, Sep 20 2010, 13:40:19) [C] on aix5
> > Type "help", "copyright", "credits" or "license" for more information.
> >>>> import numpy
> >>>> import fmodule
> >>>> def simple():
> > ...    return 'Hi there!'
> > ...
> >>>> fmodule.a(simple)
> > Traceback (most recent call last):
> >  File "<stdin>", line 1, in <module>
> > TypeError: fmodule.a() 1st argument (pyfunction) can't be converted 
> to float
> >
> > So I change "A" to specify that PYFUNCTION is a function:
> >
> >      SUBROUTINE A(PYFUNCTION)
> >      EXTERNAL PYFUNCTION
> >      CHARACTER*10 ASTRING
> >      ASTRING = ' '
> >      CALL RGSTR_FUNCTION(PYFUNCTION)
> >      CALL B(ASTRING)
> >      PRINT *, ASTRING
> >      RETURN
> >      END
> >
> > When I attempt to rebuild fmodule.so I get errors like this:
> >
> > "/tmp/tmpLEJzd5/src.aix-5.3-2.7/fmodulemodule.c", line 357.22: 
> 1506-275 (S) Unexpected text pyfunction_cptr encountered.
> > "/tmp/tmpLEJzd5/src.aix-5.3-2.7/fmodulemodule.c", line 357.3: 
> 1506-045 (S) Undeclared identifier pyfunction_typedef.
> > "/tmp/tmpLEJzd5/src.aix-5.3-2.7/fmodulemodule.c", line 371.3: 
> 1506-045 (S) Undeclared identifier pyfunction_cptr.
> >
> > And fmodule.so does not get built.
> >
> > I am hoping that someone has done something similar and can pass on
> > their wisdom.  Is this the right approach?  Is it even possible? If
> > so, is there an easier way to accomplish this kind of task?
> >
> > Any advice or a solution would be most appreciated.
> >
> > Thanks!
> >
> > Mark
> > --
> > "A mother takes twenty years to make a man of her boy, and another
> > woman makes a fool of him in twenty minutes."
> >        -- Anonymous
> >
> > _______________________________________________
> > f2py-users mailing list
> > f2py-users at cens.ioc.ee
> > 
> >
> 
> _______________________________________________
> f2py-users mailing list
> f2py-users at cens.ioc.ee
> 



More information about the f2py-users mailing list