我正在尝试在两个Fortran子例程之间插入C ++层。我还需要传递一个我不想在C ++中声明的派生类型作为参数,因为我不需要访问它的数据,并且它在我的原始程序中是一个复杂的类型,反过来使用了很多其他类型。
我做了一个简单的Fortran程序:
module my_module
implicit none
type :: my_type
real :: x
end type my_type
end module my_module
subroutine fortran_subroutine(b)
use my_module
implicit none
type(my_type), pointer, intent(in) :: b
print *, b%x
end subroutine fortran_subroutine
program test
use my_module
implicit none
abstract interface
subroutine sub (b)
import :: my_type
type(my_type), pointer, intent(in) :: b
end subroutine sub
end interface
type(my_type), pointer :: a
procedure (sub), pointer :: f_ptr => null ()
procedure (sub) :: fortran_subroutine
allocate(a)
a%x = 1.0
f_ptr => fortran_subroutine
call c_plus_plus_layer(f_ptr,a)
end program
这是C ++中间层:
extern "C"
{
void c_plus_plus_layer_(void (*pointer_to_fortran_function)(void **), void ** x);
}
// Intermediate layer of C++ designed to launch a Fortran subroutine
void c_plus_plus_layer_(void (*pointer_to_fortran_function)(void **), void ** x)
{
pointer_to_fortran_function(x);
}
但是,在使用英特尔编译器(v13)进行编译时遇到print
指令时出错,因为我在C ++层的某处丢失了存储在我的派生类型中的数据。
gcc和gfortran编译器不会返回任何内容。
我可以请求你的帮助吗?
答案 0 :(得分:5)
Fortran 2003提供了一种与C接口的新方法。模块iso_c_binding
声明了一个代表type(c_ptr)
的派生类型void*
和一个允许您通过的属性value
指针的值。它还包含用于转换Fortran和C指针的过程c_loc()
和c_f_pointer()
。
对于程序指针,类似type(c_funptr)
,程序c_funloc()
和c_f_procptr()
可用。
此外,通过使用bind(C)
属性,您可以在C ++中获得类似的效果es extern(C)
,并且您不必担心名称重整和尾随_
。 bind(C)
属性对于实现Fortran过程的真实C
行为非常重要,例如value
属性。
请注意,如果您使用bind(C)
,编译器通常会警告您甚至引发错误,即Fortran pointer
属性不能在此类过程中使用,因为C不会理解它。