c - Fortran:在英特尔 Fortran x64 中使用 C 函数

标签 c fortran

我的数据文件 (thedata.txt) 有 10 个位置,例如:

492484.94 4414814.5
418558.31 4387130.8
488518.45 4425324.5
514821.34 4414303.1
474606.53 4452659.5
488970.51 4462154.6
487880.97 4423944.5
508027.28 4437213.5
492079.38 4429661.5
449220.47 4396761.5

C文件(bidist.c)计算10*9/2=45个双边距离:

#include <math.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>

void bidist(double thedata[][2], double d2[][1], double ndata[1][1])
{
  register int i,j,k;
  double x,y;
  k=0;
  for(i=0;i<ndata[0][0];i++) {
    for(j=i+1;j<ndata[0][0];j++) {
      x = (thedata[i][0]-thedata[j][0]);
      y = (thedata[i][1]-thedata[j][1]);
      d2[k][0]= (sqrt((x*x)+(y*y)));
      k++;
    }
  }
}

我想使用“bidist”函数在 Fortran 中打印“d2” vector 。我写了一段 Fortran 代码 (main.f90):

program distance
 implicit none
 real, dimension(10,2) :: thedata
 real, dimension(45) :: d2
 integer :: i
 open(10, file='thedata.txt', status='old')
 rewind(10)
 do i=1,10
  read(10,*) thedata(i,1:2)
 end do
 call bidist(thedata,d2,10)
 print*, d2
end program distance

我运行了“cl -c bidist.c”和“ifort -c main.f90”。然后我做了“ifort -o mymain bidist.obj main.obj”。但是我有 LNK2019 错误。我该如何解决这个问题?谢谢!

最佳答案

正如@haraldkl 所指出的,我真的建议使用 iso_c_binding

说了这么多,你的代码好像有几处错误。

1) 您将数据和结果定义为 real 类型,但 bidist 函数需要 double。

您可能使用不同的实数和整数定义来调用编译器,因为我知道 ifort 可以采用 -r8 表示实数是 8 字节。但是我发现这可能会反过来咬你(如果你在使用其他编译器等时忘记添加这样的标志)。

我会使用 select_kindiso_fortran_enviso_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) bidist 中的数组定义以错误的顺序定义数组大小。请记住 C 是行优先的。

void bidist(double thedata[][10], double d2[], int ndata)

从这个意义上说,我会按照以下几行重写程序:

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

然后 bidist 为:

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++;
                }
        }

}

关于c - Fortran:在英特尔 Fortran x64 中使用 C 函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23574601/

相关文章:

python - fortran和python的解释

arrays - 返回 Fortran 中不同长度的字符串数组

python - F2PY 与具有回调参数和假定形状数组参数的子例程

c - 如何使用 Fortran 接口(interface)调用包含用户定义类型的 C 函数

loops - Fortran 中的长整数

c++ - 基本 typedef 操作数语法

c - 内核模块在使用 insmod 时被杀死

c - 小基数的高效指数

c - 从文件中读取行

c++ - 如何在C中有效地存储字符串映射?