如何使Fortran指针通过C ++

时间:2014-03-18 08:52:16

标签: c++ fortran

我正在尝试在两个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编译器不会返回任何内容。

我可以请求你的帮助吗?

1 个答案:

答案 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()可用。

在标记fortran-iso-c-binding

中学习很多问题和答案

此外,通过使用bind(C)属性,您可以在C ++中获得类似的效果es extern(C),并且您不必担心名称重整和尾随_bind(C)属性对于实现Fortran过程的真实C行为非常重要,例如value属性。

请注意,如果您使用bind(C),编译器通常会警告您甚至引发错误,即Fortran pointer属性不能在此类过程中使用,因为C不会理解它。