f_of_i | a function of 1 `int` variable |
---|---|

f_of_d | a function of 1 `double` variable |

f_of_nn | a function of 2 `int` parameters |

f_of_nd | a function of 1 `int` parameter and 1 `double` variable |

f_of_dd | a function of 2 `double` variables |

f_of_nnd | a function of 2 `int` parameters and 1 `double` variable |

f_of_ppd | a function of 2 `double` parameters and 1 `double` variable |

f_of_pppd | a function of 3 `double` parameters and 1 `double` variable |

The return values of functions are assumed to be of the `double`

type.

Note, that there is no difference from the point of view of function prototype between parameters and variables; the difference is in the way ACE/gr treats them - an attempt to use a vector expression as an parameter argument will result in a parse error.

Let us consider few examples.

`pow(x,y)`

from the Un*x math library
(libm). Of course, you can use the "The command to make it accessible by ACE/gr is

- USE "pow" TYPE f_of_dd FROM "/usr/lib/libm.so"

`my_function`

which simply returns its (second) argument multiplied
by integer parameter transferred as the first argument.
In a text editor, type in the following C code and save it as "my_func.c":

my_func.c |
---|

double my_function (int n, double x) { double retval; retval = (double) n * x; return (retval); } |

$gcc -c -fPIC my_func.c $gcc -shared my_func.o -o /tmp/my_func.so(You may strip it to save some disk space):

$strip /tmp/my_func.soThat's all! Ready to make it visible to ACE/gr as "myf" - we are too lazy to type the very long string "my_function" many times :)

- USE "my_function" TYPE f_of_nd FROM "/tmp/my_func.so" ALIAS "myf"

Suppose, the name of the library is "special_lib" and the function you are interested in is called "special_func" and according to the library manual, should be accessed as

`void special_func(double *input, double *output, int parameter)`

.
The wrapper would look like this:
my_wrapper.c |
---|

double my_wrapper(int n, double x) { extern void special_func(double *x, double *y, int n); double retval; (void) special_func(&x, &retval, n); return (retval); } |

$gcc -c -fPIC my_wrap.c $gcc -shared my_wrap.o -o /tmp/my_wrap.so -lspecial_lib -lblas $strip /tmp/my_wrap.soNote that I added

`-lblas`

assuming that the special_lib library
uses some functions from the BLAS. Generally, you have to add Fine, make ACE/gr aware of the new function

- USE "my_wrapper" TYPE f_of_nd FROM "/tmp/my_wrap.so" ALIAS "special_func"

Here we will try to achieve the same functionality as in Example 2, but with the help of F77.

myfunc.f |
---|

DOUBLE PRECISION FUNCTION MYFUNC (N, X) IMPLICIT NONE INTEGER N DOUBLE PRECISION X C MYFUNC = N * X C RETURN END |

As opposite to C, there is no way to call such a function from ACE/gr directly -
the problem is that in Fortran all arguments to a function (or subroutine) are
passed by reference. So, we need a wrapper:

myfunc_wrap.c |
---|

double myfunc_wrapper(int n, double x) { extern double myfunc_(int *, double *); double retval; retval = myfunc_(&n, &x); return (retval); } |

Note that most of f77 compilers by default add underscore to the function names
and convert all names to the lower case, hence I refer to the Fortran function
`MYFUNC`

from my C wrapper as `myfunc_`

, but in your case
it can be different!

Let us compile the whole stuff:

$g77 -c -fPIC myfunc.f $gcc -c -fPIC myfunc_wrap.c $gcc -shared myfunc.o myfunc_wrap.o -o /tmp/myfunc.so -lf2c -lm $strip /tmp/myfunc.so

And finally, inform ACE/gr about this new function:

- USE "myfunc_wrapper" TYPE f_of_nd FROM "/tmp/myfunc.so" ALIAS "myfunc"