Accessing a C array inside Fortran Sub

Accessing a C array inside Fortran Sub

Was reading the Intel web-article:

http://software.intel.com/sites/products/documentation/hpc/composerxe/en...

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] = 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?

4 posts / 0 new
Last post
For more complete information about compiler optimizations, see our Optimization Notice.

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.

Terry G.: I think that you need to replace

type(c_ptr) :: cptr_to_c_array
by
type(c_ptr), value :: cptr_to_c_array

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.

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.

Leave a Comment

Please sign in to add a comment. Not a member? Join today