我有一个C语言程序,具有一个名为get_name
的函数。此函数返回一个字符串(即char *
),并用字符串的大小更改参数size
(传递给它):
char *get_name(int &size)
{
*size = strlen(name); // name is a C global variable declared as a char *
return name;
}
我创建了以下Fortran模块以能够调用C函数get_name
:
MODULE X
USE, INTRINSIC :: iso_c_binding, ONLY: c_intptr_t
IMPLICIT NONE
INTERFACE
TYPE(c_ptr) FUNCTION get_name_(size) BIND(C, name = "get_name")
USE, INTRINSIC :: iso_c_binding, ONLY: c_int, c_ptr
INTEGER(c_int), INTENT(OUT) :: size
END FUNCTION
END INTERFACE
CONTAINS
FUNCTION get_name()
USE, INTRINSIC :: iso_c_binding, ONLY: c_int, c_char, c_f_pointer, c_ptr, c_associated
!DEC$ ATTRIBUTES DLLEXPORT :: get_name
CHARACTER(LEN = :), ALLOCATABLE :: get_name
INTEGER(c_int) :: size
TYPE(c_ptr) :: c_string
c_string = get_name_(size)
IF (c_associated(c_string)) THEN
BLOCK
CHARACTER(KIND = c_char, LEN = size), POINTER :: f_string
CALL c_f_pointer(c_string, f_string)
get_name = f_string
END BLOCK
ELSE
get_name = ""
END IF
END FUNCTION
END MODULE
我可以使用Windows中的IFORT 2016,Linux中的IFORT 2016和Linux中的gfortran成功编译此Fortran模块。
为了测试,我创建了一个简短的Fortran程序:
PROGRAM Test
USE X
WRITE(*, *) "Name: ", get_name()
END PROGRAM
我可以使用Windows中的IFORT 2016,Linux中的IFORT 2016和Linux中的gfortran成功编译此Fortran程序。
现在,在运行程序时,它在Linux的IFORT 2016,Linux的gfortran,Windows的IFORT 2016中运行良好。实际上会出现以下错误:
forrtl: severe (157): Program Exception - access violation
您知道如何解决此错误吗?
答案 0 :(得分:1)
我假设您的C函数是char *get_name(int *size)
,而不是使用C ++引用。
然后,此代码可在Windows和Linux以及Ifort 16和gcc-6.3.1或Visual Studio 2015上运行。
请添加您使用过的C编译器和命令行来编译代码。我用过:
cl -c testc.c && ifort -c testf.f /extend-source:132 && ifort testm.f testf.obj testc.obj /extend-source:132 && testm.exe
顺便说一句:如果您正在并行代码中使用此函数,我建议避免使用块构造-我在Ifort 16上并行使用此(OpenMP)代码时经验不足。