如何解决如何在 Fortran 中使用 iso_c_binding 接收数组
我正在使用 f2py 封装一个 C 库(稍后在 python/numpy 中使用它们)。在获得帮助 here 使第一个封装工作后,我现在尝试封装更复杂的类型,特别是返回通过 malloc
分配的数组的 C 函数。
这是 C 库模型 (c_lib.c):
#include <stdlib.h>
double multiply_numbers(double a,double b);
double *get_array(double a);
double multiply_numbers(double a,double b) {
return a*b;
}
double *get_array(double a) {
double *retval;
int i;
retval = malloc(100*sizeof(a));
for(i=0; i<100; i++) {
retval[i] = i*a;
}
return retval;
}
我可以成功封装基本的multiply_numbers
函数(f_mod.f90):
module test_c_lib
use iso_c_binding
implicit none
contains
subroutine multiply(x,y,z)
use iso_c_binding
real(8),intent(in) :: x
real(8),intent(in) :: y
real(8),intent(out) :: z
! Interface to C function
interface
real(c_double) function c_multiply_numbers(a,b) bind(C,name="multiply_numbers")
import
real(c_double),value :: a,b
end function
end interface
! Call C function
z = c_multiply_numbers(x,y)
end subroutine
end module
我使用这个 makefile 编译所有东西:
f_mod.so: f_mod.f90 c_lib.o
f2py -c f_mod.f90 c_lib.o -m f_mod
c_lib.o: c_lib.c
gcc -c -fpic c_lib.c -o c_lib.o
但是我正在努力理解如何编写包装 C 函数 get_array
的子例程。
具体来说,
- 如何接收 100 件物品的数组?
- 哪个是接口定义?
注意:我没有尝试任何东西,因为我不知道从哪里开始。
编辑
通过大量的注释,我已经能够封装该函数并使其工作。值得注意的是,f2py
可能需要将 Fortran 指针分配给 Fortran 数组的额外步骤。在这一点上我不确定,但是在尝试直接输出 Fortran 指针时无法编译 f2py。
这是 Fortran 中 f2py 的最终包装子例程:
subroutine get_array(x,z)
use iso_c_binding
real(8),intent(in) :: x
real(8),intent(out) :: z(100)
! Auxiliary variables to convert C pointer to Fortran Array
type(c_ptr) :: ret_c_ptr
real(8),pointer :: f_ptr(:)
! Interface to C function
interface
type(c_ptr) function c_get_array(a) bind(C,name="get_array")
import
real(c_double),value :: a
end function
end interface
! Call C function
ret_c_ptr = c_get_array(x)
call c_f_pointer(ret_c_ptr,f_ptr,[100])
! Assign Fortran pointer to Fortran output array
z = f_ptr
end subroutine
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。