c_f_pointer不起作用

c_f_pointer does not work

本文关键字:不起作用 pointer      更新时间:2023-10-16

我有一个非常简单的程序,这让我非常困惑。调用c_f_pointer不起作用,显然我犯了很多错误!

program test
use iso_c_binding
implicit none
interface
subroutine call_fc(size,status) bind(C,name='call_fc_')
  import
  integer(c_int) :: size
  type(c_ptr) :: status
end subroutine
end interface
integer(c_int) :: size=8,i
integer(c_int),pointer  :: stat(:)
type(C_ptr) :: statptr
call call_fc(size, statptr)
call c_f_pointer(statptr,stat,(/size/))
print *, 'stat is : ',stat
end program test   

C++ 子例程是

extern "C" {
void call_fc_(int *size, int *status)
{
    int i;
    for(i=0; i<*size;i++) {
        status[i] = i+10;
        printf("%d th value : %d n", i, status[i]);
    }   
}
}

当我编译并运行代码时,它将产生以下错误

0 th value : 10 
1 th value : 11 
2 th value : 12 
3 th value : 13 
4 th value : 14 
5 th value : 15 
6 th value : 16 
7 th value : 17 
Program received signal SIGSEGV: Segmentation fault - invalid memory reference. 

谁能告诉我出了什么问题?

没有为 stat/status 分配内存。

如果目标是将整数数组传递给C++子例程,则不需要c_f_pointer

program test
  use iso_c_binding
  implicit none
  interface
     subroutine call_fc(size,status) bind(C,name='call_fc_')
       import c_int
       integer(c_int) :: size
       integer(c_int) :: status(size)
     end subroutine call_fc
  end interface
  integer(c_int), parameter :: size=8
  integer(c_int) stat(size)
  call call_fc(size, stat)
  print *, 'stat is : ',stat
end program test

非常感谢。我的问题刚刚解决了,这个例子的目的只是在 C 或 C++ 子例程中分配内存并将分配的内存传递给 FORTRAN,其他明智的,我也知道没有必要这样做。

program test
use iso_c_binding
implicit none
interface
function call_fc(size) bind(C,name='call_fc')
  import :: c_int, c_ptr
  integer(c_int) :: size
  type(c_ptr) :: call_fc
end function
end interface
integer(c_int) :: size=8,i
integer(c_int),pointer  :: stat(:)
call c_f_pointer(call_fc(size),stat,(/size/))
print *, 'stat is : ',stat
end program test   

C++ 子例程是

extern "C" {
void * call_fc(int *size)
{
    int i;
    int * status = new int [*size];
    for(i=0; i<*size;i++) {
        status[i] = i+10;
        printf("%d th value : %d n", i, status[i]);
    }   
    return status;
}
}

当我编译并运行代码时,它将产生正确的答案

0 th value : 10 
1 th value : 11 
2 th value : 12 
3 th value : 13 
4 th value : 14 
5 th value : 15 
6 th value : 16 
7 th value : 17 
stat is : 10   11    12   13   14   15   16   17

我还要补充一点,如果出于某种原因想要传递type(c_ptr)(例如,能够传递null),则必须使用 value 属性,如果 C 端的参数只是按值传递的指针,如您的示例所示。

interface
  subroutine call_fc(size,status) bind(C,name='call_fc_')
    import
    integer(c_int) :: size
    type(c_ptr), value :: status
  end subroutine
end interface

即使在此之后,您的特定 C 过程也需要传递的指针指向某个有效的内存段(大小为 size*sizeof(int) )。