我试图在Fortran子程序中调用C ++函数。该C ++函数应该更新整数数组。这是我写的一个非工作代码。有什么问题?
! Fortran function that calls a C++ function.
subroutine my_function()
integer(4) ar(*)
integer(4) get_filled_ar
! Need correct syntax here.
ar = get_filled_ar()
end
// C++ function:
extern "C" {
void get_filled_ar(int *ar){
ar[0] = 1;
ar[1] = 10;
ar[3] = 100;
}
}
答案 0 :(得分:7)
使用Fortran 2003,有一种标准的,因此平台和编译器独立的方式来从Fortran调用C,以及任何使用C调用接口的语言。也是从C调用Fortran。虽然各种编译器编写者正在逐步添加Fortran 2003功能,并且几乎没有完整的2003编译器,但ISO C Binding在许多编译器中已经有一段时间了。 ISO C Binding比以前的ad hoc技术工作得更好,这些技术有时记录很少,并且在编译器和平台之间有所不同。要从Fortran调用C,您编写一个“接口”,告诉Fortran编译器它应该使用C调用约定和C类型。
这是一个例子。正如Mike写的那样,由于C ++函数返回void,因此将它作为子例程在Fortran中处理并调用它。因此,不需要给出类型。此外,在Fortran中的某个位置,您必须为数组保留存储空间 - 最简单的方法是使用维度的数值进行声明。而且你需要某种语言的主程序。
program test_call_C
use iso_c_binding
implicit none
interface c_interface
subroutine get_filled_ar (ar) bind (C, name = "get_filled_ar")
use iso_c_binding
implicit none
integer (c_int), intent (out), dimension (*) :: ar
end subroutine get_filled_ar
end interface c_interface
integer (c_int), dimension (0:3) :: ar
call get_filled_ar (ar)
write (*, *) "Fortran: ar:", ar
stop
end program test_call_C
并在C:
void get_filled_ar (
int ar []
) {
ar [0] = 1;
ar [1] = 10;
ar [2] = 100;
return;
}
示例命令:
gcc -c get_filled_ar.c
gfortran get_filled_ar.o test_call_C.f90 -o test_call_C.exe
./test_call_C.exe
要调用C ++代码,请使用以下命令。 “绑定”中指定的名称不需要使用尾随下划线,因此您的C ++代码可以直接使用。
g++ -c cplusplus.cc
gfortran cplusplus.o test_call_C.f90 -o test_call_Cplusplus.exe
./test_call_Cplusplus.exe
答案 1 :(得分:2)
这是一个完整的程序,其中包含您的代码(至少在Linux上使用gcc
/ gfortran
)。
在fortran文件fortran.f
中,输入:
IMPLICIT NONE
CALL my_function()
END
! FORTRAN function that calls a C++ function
subroutine my_function()
! Tell fortran about the C++ function:
external get_filled_ar
integer ar(4)
! As the C++ function returns void, call it as a subroutine in
! fortran:
call get_filled_ar(ar)
! To check it worked, print out the numbers:
do i = 1,4
write(*,*) i,"->",ar(i)
enddo
end
在cplusplus.cc
put:
extern "C"
{
void get_filled_ar_(int* ar) // note extra underscore to keep linker happy
{
ar[0] = 1;
ar[1] = 10;
ar[3] = 100;
}
}
然后在(使用gcc
/ gfortran
的linux上构建,在其他系统上可能会有所不同):
gfortran -c fortran.f
gcc -c cplusplus.cc
gfortran -o program-name fortran.o cplusplus.o