如何将 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 的回答。
我有以下 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 的回答。