Intel® Fortran Compiler
Build applications that can scale for the future with optimized code designed for Intel® Xeon® and compatible processors.
28386 Discussions

Accessing a C array inside Fortran Sub

Terry_G_
Beginner
300 Views

Was reading the Intel web-article:

http://software.intel.com/sites/products/documentation/hpc/composerxe/en-us/2011Update/fortran/lin/bldaps_for/common/bldaps_interopc.htm

I created a Visual Studio solution to examine the code. I added a C main project to contain a "Driver" program and a Fortran static lib project to contain the "SIMULATION" subroutine mentioned in the article. Code traps with an address exception when accessing the C defined array (C_ARRAY).

To expore further, I created a new VS solution with two projects:

1) A C main driver

#include <stdio.h>
extern void c_to_f2(int len, int* cptr_to_c_array);
int main(int argc, char* argv[])
{
  int len=9;
  int array[9];
  int n;

  for(n=0; n<len; n++)
    array = n + 10;
  c_to_f2(len, array);
  printf("Finished\n");
  return 0;
}



2) Fortran static lib project with one subroutine:


subroutine c_to_f2(len, cptr_to_c_array) bind(C)
  use iso_c_binding
  integer(c_int), value :: len
  type(c_ptr) :: cptr_to_c_array
  integer(c_int), pointer :: fptr_to_c_array(:)
  integer :: n

  call c_f_pointer(cptr_to_c_array, fptr_to_c_array, [len])
  do n=1,len
    write(*,*) fptr_to_c_array(n)   !<---- ERROR HERE
  enddo
end subroutine c_to_f2

Solution will compile and link, but traps with the same type of error when accessing the "C" array from within a Fortran subroutine.

Error: "Unhandled exception at 0x00DA5E71 in CMAIN2.PG.exe: 0xC0000005: Access violation reading location 0x0000000A."

Visual Studio debugger reports "undefined address" for each item in the "fptr_to_c_array" array.

This is the same error I encountered when executing "SIMULATION" in the Intel code.

Anybody see the problem?

0 Kudos
3 Replies
TimP
Honored Contributor III
300 Views

Did you try making what you named cptr_to_c_array a plain array of size len of type integer(c_int) ?

I know you don't more quibbles about mixing Fortran and C writes to stdout, but you really should test the limits in one way at a time.

0 Kudos
mecej4
Honored Contributor III
300 Views

Terry G.: I think that you need to replace[cpp]type(c_ptr) :: cptr_to_c_array[/cpp] by [cpp]type(c_ptr), value :: cptr_to_c_array[/cpp]

The address that your program tries to access, 0x0000000A, is actually the value that you stored in the first element of the array. Because your declaration of the subroutine did not specify VALUE for the pointer argument, a second dereferencing was attempted, leading to the illegal access.

0 Kudos
TimP
Honored Contributor III
300 Views

As mecej4 said, if you wish to work with C pointers, in such a situation they would be passed by value.  You could then use the standard intrinsic to make a Fortran pointer from it.  If you're really interested in these things, you could read about how the iso_c_binding features can be used to rationalize some legacy usage of Cray pointers.

0 Kudos
Reply