I really recommend using iso_c_binding
as @haraldkl has pointed out.
After saying this, there seems to be a few mistakes in your code.
1) You define the data and results to be of type real
yet the bidist
function is expecting doubles.
You might be calling the compiler with different definitions of real and integers, as in I know ifort
can take -r8
to say reals are 8-bytes. However I find this can come back to bite you (if you forget to add such flags when using other compilers, etc).
I would either use select_kind
or iso_fortran_env
or iso_c_binding
:
select_kind
integer, parameter :: dp = selected_real_kind(15)
real(kind=dp), dimension(10,2) :: thedata
iso_fortran_env
use, intrinsic :: iso_fortran_env
integer, parameter :: dp = REAL64
real(kind=dp), dimension(10,2) :: thedata
iso_c_binding
use, intrinsic :: iso_c_binding
real(kind=C_DOUBLE), dimension(10,2) :: thedata
2) The array definitions in bidist
define array size in the wrong order. Remember C is row-major.
void bidist(double thedata[][10], double d2[], int ndata)
In this sense I would re-write the program along the following lines:
program distance
use, intrinsic :: iso_c_binding
implicit none
real(kind=C_DOUBLE), dimension(10,2) :: thedata
real(kind=C_DOUBLE), dimension(45) :: d
integer :: i
interface
subroutine bidist(d1, d2, n) bind(C)
import
real(kind=C_DOUBLE), dimension(10,*), intent(in) :: d1
real(kind=C_DOUBLE), dimension(*), intent(inout) :: d2
integer(kind=C_INT), value, intent(in) :: n
end subroutine bidist
end interface
thedata = 0.0
d = 0.0
i = 0
open(10, file='thedata.txt', status='old')
rewind(10)
do i=1,10
read(10,*) thedata(i,1:2)
end do
call bidist(thedata, d, 10)
do i=1,45
print*, i, d(i)
end do
end program distance
And then bidist as:
void bidist(double thedata[][10], double d2[], int ndata)
{
int i = 0;
int j = 0;
int k = 0;
double x = 0.0;
double y = 0.0;
for(i=0;i<ndata;i++) {
for(j=i+1;j<ndata;j++) {
x = (thedata[0][i]-thedata[0][j]);
y = (thedata[1][i]-thedata[1][j]);
d2[k] = (sqrt((x*x)+(y*y)));
k++;
}
}
}