Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations strongm on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

Writing a C Wrapper

Status
Not open for further replies.

kirito

Programmer
Jun 3, 2011
1
HK
Hello,

I recently received a project to wrap a FORTRAN software package specifically with C (Not C++). the package is filled with subroutine with keyword and optional parameters, and I am having trouble calling these subroutines in C. I am wondering if there are some smart ways of doing it. Any help is appreciated.

Thank you.
 
You have two choices :

- the old one was to write, as you say, a C wrapper which is not portable : it depends on the compiler features like adding one or two leading or trailing underscores to Fortran procedure names

- using the Fortran 2003 iso_c_binding module puts the work on the Fortran side in a portable manner.

For instance, look at the following typical Fortran subroutine :

Code:
subroutine foo(a,b,n)
  double precision,intent(inout) :: a(n)
  real,intent(in) ::  b
  integer,intent(in) :: n
  ...
end subroutine

To make it callable by C, you just have to modify it slightly :

Code:
subroutine foo(a,b,n) bind(c,name="foo_for_c")
  use iso_c_binding
  real(c_double),intent(inout) :: a(n)
  real(c_float),intent(in) :: b
  integer(c_int),intent(in) :: n
  ...
end subroutine
[code]

And from the C side, the signature is :

[code]
void foo_for_c(double*a,float*b,int*n);

It is also possible to pass input scalar arguments by value if you prefer. But you have to take care about the call statements to "foo" in the Fortran side (the rest of the Fortran code must be aware about the "value" mode). For instance :

Code:
subroutine foo(a,b,n) bind(c,name="foo_for_c")
  use iso_c_binding
  real(c_double),intent(inout) :: a(n)
  real(c_float),value,intent(in) :: b
  integer(c_int),value,intent(in) :: n
  ...
end subroutine
[code]

And from the C side, the signature becomes :

[code]
void foo_for_c(double*a,float b,int n);

You may also choose the same procedure name from the two sides ("foo" instead of "foo_for_c")



François Jacq
 
Hi, FJ:

As of yesterday, I came into the need of the exact same thing; I followed your suggestion and things seem to compile and run just fine for as long as I never attempt to manipulate the arrays...but as soon as I add code for array, things do not even compile.

Here is the Fortran subroutine:
!============================================
subroutine fnet(n,a,b) bind(c,name="fnet")
use iso_c_binding
integer (c_int) :: n
real (c_double) :: b
real (c_double) :: a(n)

integer i

b = n*2.0

! do i = 1,n
! a(i) = 1.0*i
! end do

return
end
!============================================

Here is the calling C program:
!============================================
#include <stdio.h>
void foo(int *n, double *a, double *b);

int main(int argc, char *argv[] )
{
int n;
double a[9];
double b;

n=10 ;

fnet(&n,a,&b);

fprintf(stderr, "b = %f\n", b);

return(0) ;
}
!============================================

And here are the error messages when attempting to compile the programs after uncommenting the commented lines in the Fortran subroutine.

g95 -i4 -r8 -fzero -fstatic -fbounds-check -fno-underscoring -fsloppy-char -O2 -ftrace=none -c fnet.f90 -o lnx/fnet.o
gcc -msse -msse2 -mfpmath=sse -O2 -c testc.c -o lnx/testc.o
gcc -static -s -o lnx/testc.exe lnx/fnet.o lnx/testc.o -lm
lnx/fnet.o(.text+0xaf): In function `fnet':
: undefined reference to `_g95_filename'
lnx/fnet.o(.text+0xb9): In function `fnet':
: undefined reference to `_g95_line'
lnx/fnet.o(.text+0xc2): In function `fnet':
: undefined reference to `_g95_array_oob2'
collect2: ld returned 1 exit status
make: *** [lnx/testc.exe] Error 1

Any ideas what this is due to?

Thanks

gsal

 
When linking a Fortran/C application, use the fortran command because it knowns how to find all libraries automatically


François Jacq
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top