Anonymous Monk has asked for the wisdom of the Perl Monks concerning the following question:
|
|---|
| Replies are listed 'Best First'. | |
|---|---|
|
Re: perl calling FORTRAN calling perl?
by almut (Canon) on Sep 25, 2007 at 12:47 UTC | |
If I'm understanding you correctly, you'd like to write a Perl binding to a Fortran lib containing a function such as
from Dierckx's fitpack, where rad is the user-defined callback routine in question, which the user of the Perl binding of course wants to write in Perl
Although this is possible, it's a bit involved, as the flow of execution has to go through a layer of C glue code in both directions... Anyway, I tried to put together a minimal example, which will hopefully get you started. Unfortunately, it's still rather lengthy... I've tested it with the g77 GNU Fortran compiler, but things should in principle work similarly with other compilers. Let's assume we have the following Fortran code
This defines a function myfunc which we're going to call from Perl. It takes three arguments, the last one of which is normally expected to be a reference to a user-defined Fortran function (declared as external in the calling Fortran code). The latter function is supposed to be implemented as a user-defined Perl routine here. Ok, the first step is to compile the Fortran code:
The resulting object file myfunc.o is what you need to link the Perl extension against. Next, create a project working directory for the extension and populate it with the necessary files. There are several ways to do this... one of them would be to use h2xs. For example
where "P2f2p" is the name of the extension ("Perl-to-Fortran-to-Perl" — couldn't think of a better name). This creates several files and directories, most importantly P2f2p.xs and Makefile.PL. However, P2f2p.xs is just a default stub file like this
so you need to modify it to actually do something:
(To keep things as concise as possible, I chose to put all code in this .xs file... In a larger project, you could of course do it proPerly and put stuff in separate .h/.c files...) Then, modify Makefile.PL to have the generated Makefile issue commands to link against the Fortran object (myfunc.o) and g77 runtime support lib (libg2c.so), i.e. change
in WriteMakefile(...) to read:
Lastly, don't forget to copy myfunc.o into the P2f2p project directory. Having completed those steps, you're ready to do the usual
(The make test isn't doing much — without any other tests having been written, it just checks if the extension can be loaded.) Now, if you're like many people, you probably don't want to install the newly created extension system-wide yet, in order to just play around with it. Of course, you could've messed with PREFIX= and friends, but the easiest way might be to simply copy the important two files into some testing directory:
Then you can write a little test script (and place it in the same test directory):
When you run it, it should print
So what's happening in detail? P2f2p::myfunc is calling XS_P2f2p_myfunc under the hood, which is the XS wrapper function as expanded by xsubpp. This function stores the reference to the passed in user-defined Perl routine, and then calls myfunc, which in turn calls the actual Fortran function myfunc_ (note the underscore, as automatically appended by g77), passing it a pointer to the callback wrapper function userfunc_wrapper. The wrapper is responsible for calling the real Perl routine (via call_sv) and handling its arguments (see perlcall for what all those macros are doing). It is being called from within the Fortran code, and is expected to return some value computed by Perl. (I'll leave it as an exercise for the reader to figure out how this all results in the final 42.) Good luck! | [reply] [d/l] [select] |
by Anonymous Monk on Sep 25, 2007 at 15:12 UTC | |
| [reply] |
|
Re: perl calling FORTRAN calling perl?
by perlfan (Parson) on Sep 24, 2007 at 23:36 UTC | |
If the former, then I suggest creating an interactive fortran program that take in all arguments via STDIN (interactively, though). Once you have that, you can easily create a simple Perl (or even shell) front end that creates whatever interface you want around it. I actually recommend a shell script in this case.
If the latter, then I have no idea. And I am confused because it sounds like you are saying that fortran (77) subs take subroutine (the fortran kind) as arguments. I don't think that is true. Finally, if you are thinking about calling a Perl program via fortran's "system" call, I have one bit of advice - don't. Figure out a way around this if at all possible. | [reply] [d/l] |
by Anonymous Monk on Sep 25, 2007 at 17:52 UTC | |
FORTRAN has been able have a subroutine/function name as an argument to a subroutine/function for a long time. There are lots of math problems which require this. | [reply] |