Re: [f2py] Unexpected text pyfunction_cptr encountered
Pearu Peterson <[email protected]> Sat, 16 Oct 2010 21:48:59 +0300
| Newsgroups | gmane.comp.python.f2py.user |
|---|---|
| Message-ID | <[email protected]> |
Hi, The ending 'E' problem is now fixed in numpy git repo. Pearu On Sat, Oct 16, 2010 at 8:44 PM, <[email protected]> wrote: > 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 <[email protected]> > 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-Y4l6ocDipWCuvFJfX82//[email protected]> > > >> 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 >> <[email protected]> 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-Y4l6ocDipWCuvFJfX82//[email protected] >> > >> > >> >> _______________________________________________ >> f2py-users mailing list >> f2py-users-Y4l6ocDipWCuvFJfX82//[email protected] >> > > _______________________________________________ > f2py-users mailing list > f2py-users-Y4l6ocDipWCuvFJfX82//[email protected] > http://cens.ioc.ee/mailman/listinfo/f2py-users >