This is the example I concocted to help demonstrate the problem and help me learn how to solve it. The problem is, I solved this … without any fancy interface blocks or anything strange like that. Go figure.
The makefile
`<code>
CC = icc
FC = ifort
LD = ifort
CFLAGS = -g
FFLAGS = -g
LFLAGS = -g
all: test.exe
test.exe: test_f.o test_c.o
$(LD) $(LFLAGS) test_f.o test_c.o -o test.exe
test_f.o: test.f90
$(FC) $(FFLAGS) -c $< -o test_f.o
test_c.o: test.c
$(CC) $(FFLAGS) -c $< -o test_c.o
clean:
rm -f *.o *.exe
</code>
`
the test.f90 code:
`<code>
program test
integer, allocatable, dimension(:,:) :: a
integer :: b
integer :: n,m,i,j
real, allocatable, dimension(:,:) :: c
! -- allocate a and c as 10x10 arrays, and fill with sequential integers
allocate(a(10,10))
allocate(c(10,10))
do i=1,10
do j=1,10
a(i,j)=10*(i-1)+j
c(i,j)=dble(10*(i-1)+j)
enddo
enddo
n=10
m=10
print *,'In test.f90: printing out 1 column of a and then c'
print *,'a:'
do j=1,10
print *,'a(1,',j,') = ',a(1,j)
enddo
print *, ' '
print *,'c:'
do j=1,10
print *,'c(1,',j,') = ',c(1,j)
enddo
call test_c(n,m,a,c)
end program
</code>
`
the test.c code:
`<code>
#include <stdio.h>
void test_c_(
int *n,
int *m,
int *a,
float *c
)
{
int i,j;
printf("in test.c: n=%i, m=%i, a=%x, c=%x\n",*n,*m,a,c);
for(i=0;i<*m;i++)
{
printf("a(%i,0)=%i\n",i,*(a+ (*m)*i+0));
}
for(i=0;i<*m;i++)
{
printf("c(%i,0)=%f\n",i,*(c+ (*m)*i+0));
}
return;
}
</code>
`
What is of interest is that Fortran includes metadata in its internal symbol tables that C doesn’t have access to. So you can’t write the C arrays as a[i][j], as this symbol metadata never traversed the language barrier. You have to do pointer arithmetic. Notice how it is done.
`<code>
a[i][j] -> *(a + j * DIMENSION_ALONG_J + i)
</code>
`
which is equivalent to a(j-1,i-1) in Fortran90. Nice little Rosetta stone we have here :) When you run the code, this is what you get
`~/testcase$ ./test.exe
In test.f90: printing out 1 column of a and then c
a:
a(1, 1 ) = 1
a(1, 2 ) = 2
a(1, 3 ) = 3
a(1, 4 ) = 4
a(1, 5 ) = 5
a(1, 6 ) = 6
a(1, 7 ) = 7
a(1, 8 ) = 8
a(1, 9 ) = 9
a(1, 10 ) = 10
c:
c(1, 1 ) = 1.000000
c(1, 2 ) = 2.000000
c(1, 3 ) = 3.000000
c(1, 4 ) = 4.000000
c(1, 5 ) = 5.000000
c(1, 6 ) = 6.000000
c(1, 7 ) = 7.000000
c(1, 8 ) = 8.000000
c(1, 9 ) = 9.000000
c(1, 10 ) = 10.00000
in test.c: n=10, m=10, a=129a030, c=129a1d0
a(0,0)=1
a(1,0)=2
a(2,0)=3
a(3,0)=4
a(4,0)=5
a(5,0)=6
a(6,0)=7
a(7,0)=8
a(8,0)=9
a(9,0)=10
c(0,0)=1.000000
c(1,0)=2.000000
c(2,0)=3.000000
c(3,0)=4.000000
c(4,0)=5.000000
c(5,0)=6.000000
c(6,0)=7.000000
c(7,0)=8.000000
c(8,0)=9.000000
c(9,0)=10.000000
`
So it works. Without an interface block. And indexing is basically correct. The hex address pointers appear to be valid. Now how to translate this to the code we are having trouble with … [updated … fixed my indexing errors…]