问题描述
我正在使用 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 (将#修改为@)