通过 Intel 文档中的 C 从 C 调用 Fortran 的示例ISO_C_BINDING
不是很清楚。但在其他地方,我发现了这样的解释:TYPE (C_PTR) :: X
相当于 C 的void **
,即指向 void 指针的指针。我们需要void *
一个 void 指针,因此必须C_ARR
使用VALUE
属性声明:
SUBROUTINE SUBR(N, C_ARR) BIND(C)
USE, INTRINSIC :: ISO_C_BINDING
IMPLICIT NONE
INTEGER (C_INT), VALUE :: N
TYPE (C_PTR), VALUE :: C_ARR
REAL (C_FLOAT), POINTER :: F_ARR(:)
CALL C_F_POINTER(C_ARR, F_ARR, (/N/))
PRINT *, F_ARR
END SUBROUTINE
但我不确定你是否需要打电话C_F_POINTER
。以下也有效:
SUBROUTINE SUBR(N, ARR) BIND(C)
USE, INTRINSIC :: ISO_C_BINDING
IMPLICIT NONE
INTEGER (C_INT), VALUE :: N
REAL (C_FLOAT) :: ARR(N)
PRINT *, ARR
END SUBROUTINE
(也许使用是一种好习惯C_F_POINTER
,我不知道。这是英特尔文档应该显示的内容:何时需要,何时不需要。)
编辑:在英特尔示例中对接口进行了更多研究后,我认为C_F_POINTER
那里需要调用,因为数组是 C 的一部分struct
。在声明您的 时TYPE
,您不能将成员数组设为可变长度,因此您必须将数据成员声明为TYPE (C_PTR)
并执行C_F_POINTER
例程。
因此,这是将指针传递给已清理的结构的相同示例:
SUBROUTINE SUBR_STRUCT(OBJ) BIND(C)
USE, INTRINSIC :: ISO_C_BINDING
IMPLICIT NONE
TYPE, BIND(C) :: VECTOR
INTEGER (C_INT) :: LEN
TYPE (C_PTR) :: DATA
END TYPE VECTOR
TYPE (VECTOR), INTENT(IN) :: OBJ
REAL (C_FLOAT), POINTER :: ARR(:)
CALL C_F_POINTER (OBJ%DATA, ARR, (/OBJ%LEN/))
PRINT *, ARR
END SUBROUTINE
这是从 C 调用的,因此:
struct obj
{
int len;
float *data;
};
extern void subr_struct(const struct obj *);
int main(int argc, char **argv)
{
float data[] = {0.12, 0.15, 0.18, 0.23, 0.29};
struct obj o = {5, data};
subr_struct(&o);
return 0;
}
如果您提供属性OBJ
,您也可以按值传递结构。VALUE