gpt4 book ai didi

c++ - 如何让 Fortran 指针在 C++ 中穿行

转载 作者:行者123 更新时间:2023-11-30 01:18:37 24 4
gpt4 key购买 nike

我正在尝试在两个 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);
}

但是,在使用 Intel 编译器 (v13) 进行编译时,当到达 print 指令时出现错误,因为我丢失了存储在 C++ 层某处的派生类型中的数据。

gcc 和 gfortran 编译器不返回任何内容。

我可以请求你的帮助吗?

最佳答案

Fortran 2003 有一种与 C 接口(interface)的新方法。模块 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++ 中的 extern(C) 类似的效果,并且您不必担心名称重整和尾随 _bind(C) 属性对于实现 Fortran 过程的真正 C 行为很重要,例如 value 属性。

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

关于c++ - 如何让 Fortran 指针在 C++ 中穿行,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22474364/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com