如何将 C++ 指针传递给 Fortran?

How to pass C++ pointer to Fortran?

我有以下 C++ 代码:

extern "C" void C_ASSIGN_ARRAY_TO_FORTRAN(double *doublearray)
{
    doublearray=new double [10];
    for (int i=0;i<10;i++)
        doublearray[i]=i;
}

应将数组 doublearray 传递给 Fortran:

  USE, INTRINSIC :: ISO_C_BINDING
  IMPLICIT NONE
  INTERFACE
    SUBROUTINE C_ASSIGN_ARRAY_TO_FORTRAN(cdoublearray) BIND(C, NAME='C_ASSIGN_ARRAY_TO_FORTRAN')
    USE, INTRINSIC :: ISO_C_BINDING
      IMPLICIT NONE
      TYPE(C_PTR)  :: cdoublearray
    END SUBROUTINE 
  END INTERFACE

  TYPE(C_PTR) :: cdoublearray
  REAL(C_DOUBLE), POINTER :: fdoublearray(:)
  CALL C_ASSIGN_ARRAY_TO_FORTRAN((cdoublearray))
  CALL C_F_POINTER( cdoublearray, fdoublearray,[10])  
  WRITE (*, *) fdoublearray
  END   

然而,代码在 C_F_POINTER 处崩溃:调用 C_ASSIGN_ARRAY_TO_FORTRAN 后,cdoublearray 等于 0。 谁能帮我看一下?

您正在按值而不是按引用传递指针。您的 C++ 代码应为

extern "C" void C_ASSIGN_ARRAY_TO_FORTRAN(double *& doublearray)
{
    doublearray=new double [10];
    for (int i=0;i<10;i++)
        doublearray[i]=i;
}

注意 C_ASSIGN_ARRAY_TO_FORTRAN(double *& doublearray)

另一种使用 C 指针的方法(感谢 Vladimir)可能如下所示:

extern "C" void C_ASSIGN_ARRAY_TO_FORTRAN(double ** doublearray)
{
    double *arr = new double [10];
    for (int i=0;i<10;i++) 
        arr[i]= i;
    *doublearray = arr;
}

使用 Vladimir 建议的修复,Fortran 代码如下

program test
  USE, INTRINSIC :: ISO_C_BINDING
  IMPLICIT NONE
  INTERFACE
    SUBROUTINE C_ASSIGN_ARRAY_TO_FORTRAN(cdoublearray) BIND(C, NAME='C_ASSIGN_ARRAY_TO_FORTRAN')
    USE, INTRINSIC :: ISO_C_BINDING
      IMPLICIT NONE
      TYPE(C_PTR)  :: cdoublearray
    END SUBROUTINE 
  END INTERFACE

  TYPE(C_PTR) :: cdoublearray
  REAL(C_DOUBLE), POINTER :: fdoublearray(:)

  CALL C_ASSIGN_ARRAY_TO_FORTRAN( cdoublearray )
  CALL C_F_POINTER( cdoublearray, fdoublearray,[10])

  WRITE (*, *) 'fdoublearray',fdoublearray
END program

那么,输出就是

./a.out 
 fdoublearray   0.0000000000000000        1.0000000000000000        2.0000000000000000        3.0000000000000000        4.0000000000000000        5.0000000000000000        6.0000000000000000        7.0000000000000000        8.0000000000000000        9.0000000000000000 

您正在传递指针的副本

CALL C_ASSIGN_ARRAY_TO_FORTRAN((cdoublearray))

复制由第二组括号完成。因此 cdoublearray 永远不会改变并保留原始的未定义值,这恰好是 e 0.

尝试

CALL C_ASSIGN_ARRAY_TO_FORTRAN(cdoublearray)

但要小心,在释放数组时你仍然会遇到问题。这必须从 C++ 完成。

您还必须调整过程以接受指向指针的指针。请参阅@AlexenderVogt 的回答。