Frage

I've looked around, and though there are a lot of EXC_BAD_ACCESS issues, none of them helped.

I'm using Mountain Lion (OSX 10.8 I think?), and PGI 12.

I can't seem to call fortran functions from C, I've written a simplified case and it seems that I can't pass integers.

My fortran function is:

  1 integer function smallFortran(a) result(res) bind(c,name='smallFortran_')
  2 !integer function smallFortran(a) result(res)
  3     
  4     use ISO_C_BINDING
  5     implicit none
  6     
  7     integer(kind=c_int), intent(IN) :: a
  8     !integer, intent(IN) :: a
  9     
 10     print *,'A = ', a
 11     res = a;
 12 
 13 endfunction smallFortran

And my C function is,

int main() {
   int ier=7;
   ier = smallFortran_(8);
}

Build it..

matt@pontus:diffFst$ make                                                                                                               
pgcc -c cDoDiffFst.c                                                                                                                    
PGC-W-0267-#warning --  "Unsupported compiler detected" (/usr/include/sys/cdefs.h: 81)                                                  
PGC/x86-64 OSX 12.9-0: compilation completed with warnings                                                                              
pgcc -g -O0 -traceback -o cDoDiffFst cDoDiffFst.o smallFortran.o -lpgf90 -lpghpf2 -lpgf90rtl -lpgftnrtl -lpghpf_rpm

(I hope that warning isn't what's causing my problems, the PGI user forum responds to this by saying they'll send a newer version of the file, but I haven't been replied to yet. And no idea why PGI requires so many extra libraries to be specified)

When I run it in the debugger..

matt@pontus:diffFst$ gdb cDoDiffFst                                                                                                     
(gdb) run
Starting program: /Users/matt/aurams/trunk/utils/diffFst/cDoDiffFst 
Reading symbols for shared libraries +............................. done

Program received signal EXC_BAD_ACCESS, Could not access memory.
Reason: KERN_INVALID_ADDRESS at address: 0x0000000000000008
0x0000000100001906 in _smallFortran_ (a=Cannot access memory at address 0x8
) at smallFortran.f90:10
10              print *,'A = ', a
(gdb)

I'm totally lost, why can't I send an int? I've tried assigning a value to an integer and sending it, no dice. I've tried it as a subroutine, I've tried it without a return value.. nothing works.

War es hilfreich?

Lösung 2

The error should make clear what's going wrong; smallFortran_ expects its argument to be passed by reference (as are all arguments in fortran -- note that I'm being slightly fast and loose here), and tries to access the data at the pointer 8, which fails. Fix is easy; the function expects a pointer, so give it one:

int main() {
  int ier = 7;
  int arg = 8;
  ier = smallFortran_(&arg);
}

This assumes that the fortran integer type corresponds to a C int with the compilers in question; you may need to make arg a long otherwise.

Andere Tipps

Here is an alternative solution that shows how to write Fortran to match the original C of the question. The key is the value qualifier on the declaration. With the Fortran ISO C Binding you match various ways C passes arguments. You can also do away with underscores in routine names ... that's a purpose of the name keyword of bind.

The C code without the underscore in the call:

int main() {
   int ier=7;
   ier = smallFortran (8);
}

and the matching Fortran:

function smallFortran(a) result(res) bind(c,name='smallFortran')

     use ISO_C_BINDING
     implicit none

     integer(kind=c_int), intent(IN), value :: a
     integer(kind=c_int) :: res

     print *,'A = ', a
     res = a;

 endfunction smallFortran
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top