试图处理Fortran指针 - 调用c_f_pointer

时间:2018-05-16 14:41:19

标签: c pointers fortran wrapper fortran-iso-c-binding

使用后尝试处理Fortran指针时遇到问题: call c_f_pointer(dataPtr, dataF, [natoms,countf]),其中dataPtr是带有intent(in)dataF的C指针,是intent(out)的Fortran指针。

natomscountf是用于定义输出指针大小的整数。

先前将变量声明为:

use, intrinsic :: iso_c_binding
integer natoms, countf
type(c_ptr) dataPtr
real(c_float), pointer :: dataF(:,:) => NULL()

dataPtr来自另一个函数。

如果我打印shape(dataF),我会得到正确的结果。但我无法使用dataF打印或复制或执行任何操作。我得到的错误是 forrtl:严重(174):SIGSEGV,发生了分段错误

我遵循了https://software.intel.com/en-us/node/678433示例,我可以毫无问题地编译和操作。

编辑:添加更多代码。

program test

use, intrinsic :: iso_c_binding
implicit none

interface
    subroutine open(ptr) bind(c, name='open')
        use, intrinsic :: iso_c_binding
        implicit none
        type(c_ptr), intent(out) :: ptr
    end subroutine open
    subroutine gather(ptr, name, typ, countf, data) bind(c, name='gather')
        use, intrinsic :: iso_c_binding
        implicit none
        type(c_ptr), value, intent(in) :: ptr
        type(c_ptr), value, intent(in) :: name
        integer(c_int), value, intent(in) :: typ
        integer(c_int), value, intent(in) :: countf
        type(c_ptr), intent(out) :: data
    end subroutine gather
    subroutine scatter(ptr, name, typ, countf, data) bind(c, name='scatter')
        use, intrinsic :: iso_c_binding
        implicit none
        type(c_ptr), value, intent(in) :: ptr
        type(c_ptr), value, intent(in) :: name
        integer(c_int), value, intent(in) :: typ
        integer(c_int), value, intent(in) :: countf
        type(c_ptr), intent(in) :: data
    end subroutine scatter
end interface

integer natoms, countf, typ
character(len=2,kind=c_char) :: var = c_char_'x'//c_null_char
type(c_ptr) ptr, dataPtr
real(c_float), pointer :: dataF(:,:) => NULL()

!opens an instance of the program (loaded as library into my Fortran)
!ptr is a pointer used to reference to it in other calls
call open(ptr)

!Here comes definitions for the integer variables
!...

!get data
call gather(ptr, c_loc(var), typ, countf, dataPtr)

!need to do stuff with the data here
call c_f_pointer(dataPtr, dataF, [natoms,countf])

!return modified data
call scatter(ptr, c_loc(var), typ, countf, dataPtr)

如果我只是获取数据call gather(...)然后将其返回call scatter(...),则该程序可以正常运行。但我需要在两者之间做些事情。

EDIT2:添加了C函数

void open(void **ptr) {
// ...
}

void gather(void *ptr, const char *name,
                     int type, int count, void *data) {
// ...
}

void scatter(void *ptr, const char *name,
                     int type, int count, void *data) {
// ...
}

1 个答案:

答案 0 :(得分:0)

显然我明白了。

首先,数据指针必须在子程序def gen(self, arg1, arg2, optional): if optional exists do that: print(optional) else: print(arg1, arg2) 中输入intent(in)value

gather

我改变了subroutine gather(ptr, name, typ, countf, data) bind(c, name='gather') ! ... type(c_ptr), value, intent(in) :: data ! instead of: ! type(c_ptr), intent(out) :: data end subroutine gather 的声明,不需要再从dataF调用:

c_f_pointer

所以我删除了real(c_float), target, allocatable :: dataF(:,:) 并添加了:

call c_f_pointer(dataPtr, dataF, [natoms,countf])

现在,allocate(dataF(natoms,countf)) dataPtr = c_loc(dataCFloat) 直接包含更新的数组。