2

我正在尝试获取 Fortran 代码库以使用 ISO_C_BINDING 调用 C 库调用,但在传递 Fortran 数组时遇到问题。

我创建了一个简单的示例来说明我的问题。

main.f90

program main
    use iso_c_binding
    implicit none

    interface
            subroutine stuff(s,d) bind(c,name='doStuff')
                    import :: c_char
                    import :: c_ptr
                    import :: c_double

                    character(c_char), value :: s
                    type(c_ptr), value :: d
            end subroutine stuff
    end interface

    character(len=1) ::c1
    real, allocatable :: d1(:)

    c1 = 'a'
    allocate ( d1(0:10) )

    d1(0) = 2.0
    d1(1) = 2.5
    d1(2) = 3.0
    d1(3) = 4.0

    write (*,*) d1

    call stuff(c1,c_loc(d1))

end program main

函数c

//a function
int doStuff (char c, double* w)
{
    printf("%c\n",c);
    printf("%d %d %d %d\n",w[0], w[1], w[2], w[3]);
    return 1;
}

编译行

icc -c func.c
ifort -o magic.go main.f90 func.o

输出

2.000000       2.500000       3.000000       4.000000      0.0000000E+00    0.0000000E+00  0.0000000E+00  0.0000000E+00  0.0000000E+00  0.0000000E+00  0.0000000E+00
a
0 -1938231792 1 1

char 被正确传递,但数组不是,我不知道如何更正它。我见过的例子建议改变

double* w

void* w

但我不能这样做,因为我无法更改库代码来完成这项工作。我只是尝试创建一个新函数来将 avoid*强制double*转换为无效:(。同样地更改数组使其不可分配是不可行的。

想法?

4

1 回答 1

3

你的声明有问题d1。会更好

real(c_double), allocatable, target :: d1(:)

也就是说:它必须是正确的类型才能与 C 的 double 互操作;要成为它的参数,c_loc它必须具有targetorpointer属性。

此外,正如 Mahonri Moriancumer 所指出的,您的printf格式不适合双打。并且,可能stuff值得考虑将其作为函数而不是子程序。

于 2014-05-21T22:04:37.773 回答