我正在尝试使用ISO_C_BINDING来调用C语言调用Fortran代码库,但是我在传递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
func.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
但我无法做到这一点,因为我无法更改库代码以使其工作。我刚刚尝试创建一个新功能,将void*
转换为double*
无效:(。
同样地改变数组以使其不可分配是不可行的。
思想?
答案 0 :(得分:2)
您对d1
的声明有疑问。更好的是
real(c_double), allocatable, target :: d1(:)
那就是:它需要是与C的双重互操作的正确类型;要成为c_loc
的参数,它必须具有target
或pointer
属性。
另外,正如Mahonri Moriancumer所述,您的printf
格式不适合双重格式。并且,可能将stuff
作为函数而不是子例程可能值得考虑。