Re: [f2py] Unexpected text pyfunction_cptr encountered
[email protected] Sat, 16 Oct 2010 13:44:07 -0400
| Newsgroups | gmane.comp.python.f2py.user |
|---|---|
| Message-ID | <[email protected]> |
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] >