binding在C中使用Fortran函数

binding在C中使用Fortran函数

本文介绍了关于使用iso_c_binding在C中使用Fortran函数的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

限时删除!!

我学习Fortran的C互操作性几天,从C中调用一个Fortran函数DLL
在这里我找到了这个链接:



我尝试创建一个像这样的Fortran DLL和我的编译器是英特尔Fortran编译器:

 模块集成
隐式无

包含

函数Integrate(func,a,b,intsteps)结果(整数)
!DEC $ ATTRIBUTES DLLEXPORT ::集成
接口
实函数func(x)
(in):: x
结束函数func
结束接口

real ::整数,a,b
整数:: intsteps
intent(in):: a,b,intsteps
可选:: intsteps

real :: x,dx
整数:: i,n
整数,参数:: rk = kind(x)

n = 1000
if(present(intsteps))n = intsteps

dx =(ba )/ n

积分= 0.0_rk
do i = 1,n
x = a +(1.0_rk * i - 0.5_rk)* dx
积分=积分+ func(x)
end do

整数=整数* dx
结束函数

结束模块整合


real(c_float)函数wrapper_integrate(func,a,b,intsteps)result(整型)bind(C,name ='integrate')
使用iso_c_binding
使用整合

$ interface
真实(c_float):: iFunc $ b $真实(c_float),intent(in)$ b $函数iFunc(x)绑定(C)
使用,内部:: iso_c_binding
真实:: x
结束函数iFunc
结束接口

类型(C_FUNPTR),INTENT(IN),VALUE :: func
real(c_float):: a, b
整数(c_int),意图(in):: intsteps
可选:: intsteps

过程(iFunc),指针:: myfunc
调用c_f_procpointer(func ,myfunc)

if(present(intsteps))then
integral = Integrate(myfunc,a,b,intsteps)&l t; ==错误#8128
else
integral = Integrate(myfunc,a,b)< ==错误#8128
endif

结束函数wrapper_integrate

当我构建DLL时,错误如下所示

 错误#8128:关联的实际过程的BIND属性与伪过程的BIND属性不同。 [MYFUNC] 

代码中表示的错误行看起来像 myfunc 不等于模块集成中定义的 func 。也许我可以使用 iso_c_binding 修改模块集成



iso_c_binding 不是一种简单的方法。所以如何解决 MYFUNC 中的错误?

解决方案

过程有一个明确的接口,那么它的特征必须与实际过程的特征相同,除了这里的一些不相关的东西。

过程的特征包括是否具有BIND属性。为了使特征保持一致,您可以使用一个没有BIND(C)的中间过程来调用您提供的BIND(例如,通过一些其他更改来避免假设c_float和c_int是否指定了默认的实数类型和整数类型:
$


 函数wrapper_integrate(func,a,b,intsteps)& 
使用集成
隐式无
$ b接口
函数(整型) func(x)bind(C)
use,intrinsic :: iso_c_binding
implicit none
real(c_float),intent(in):: x
real(c_float):: func
结束函数func
结束接口

实数(c_float),intent(in):: a,b
整数(c_int),intent(in),可选:: intsteps
real(c_float):: integral
$ b real :: local_a,local_b
integer :: local_intsteps

local_a = a
local_b = b
if(present(intsteps))then
local_intsteps = intsteps
integral = Integrate(local_func,a,b,local_intsteps)
else
整数= Integrate(local_func,a,b)
end如果
包含
函数local_func(x)
real,intent(in):: x
real :: local_func

real(c_float):: local_x

local_x = x
local_func = func(local_x)
结束函数local_func
结束函数wrapper_integrate

请注意,在可互操作的过程中存在可选参数是Fortran 2015的一项功能。


I learn Fortran's C interoperability for a few days to call a Fortran function DLL from C.Here I found this link:Use Fortran-code in C

I try to create a Fortran DLL like this and my compiler is Intel Fortran compiler:

module integration
  implicit none

contains

  function Integrate(func, a,b, intsteps) result(integral)
!DEC$ ATTRIBUTES DLLEXPORT :: Integrate
    interface
      real function func(x)
        real, intent(in) :: x
      end function func
    end interface

    real :: integral, a, b
    integer :: intsteps
    intent(in) :: a, b, intsteps
    optional :: intsteps

    real :: x, dx
    integer :: i,n
    integer, parameter :: rk = kind(x)

    n = 1000
    if (present(intsteps)) n = intsteps

    dx = (b-a)/n

    integral = 0.0_rk
    do i = 1,n
      x = a + (1.0_rk * i - 0.5_rk) * dx
      integral = integral + func(x)
    end do

    integral = integral * dx
  end function

end module integration


    real(c_float) function wrapper_integrate(func, a, b, intsteps) result(integral) bind(C, name='integrate')
  use iso_c_binding
  use integration

 interface
    function iFunc(x) bind(C)
      use, intrinsic :: iso_c_binding
      real(c_float) :: iFunc
      real(c_float), intent(in) :: x
    end function iFunc
  end interface

  type(C_FUNPTR), INTENT(IN), VALUE :: func
  real(c_float) :: a,b
  integer(c_int),intent(in) :: intsteps
  optional :: intsteps

  procedure(iFunc),pointer :: myfunc
  call c_f_procpointer(func, myfunc)

  if (present(intsteps)) then
    integral = Integrate(myfunc,a,b,intsteps)   <==error #8128
  else
    integral = Integrate(myfunc,a,b)          <==error #8128
  endif

end function wrapper_integrate

When I built the DLL, the error shows below

error #8128: The BIND attribute of the associated actual procedure differs from the BIND attribute of the dummy procedure.   [MYFUNC]

The error line denoted in code, it looks like myfunc is not equal to func defined in module integration. Maybe I can use the iso_c_binding to modify module integration.

Sometimes some Fortrans function have many arguments to be assigned and used in the function, it is not easy way to use iso_c_binding in Fortran. So how to solve the error in MYFUNC?

解决方案

If a dummy procedure has an explicit interface, then its characteristics must be the same as the characteristics of the actual procedure, except for some things not relevant here.

The characteristics of a procedure include whether it has the BIND attribute.

To make the characteristics consistent you can use a little intermediate procedure, that does not have BIND(C), to call your supplied BIND(C) procedure.

For example, with some other changes to avoid assumptions around whether c_float and c_int nominated default real and integer kinds:

function wrapper_integrate(func, a, b, intsteps)  &
    result(integral) bind(C, name='integrate')
  use iso_c_binding
  use integration
  implicit none

  interface
    function func(x) bind(C)
      use, intrinsic :: iso_c_binding
      implicit none
      real(c_float), intent(in) :: x
      real(c_float) :: func
    end function func
  end interface

  real(c_float), intent(in) :: a,b
  integer(c_int), intent(in), optional :: intsteps
  real(c_float) :: integral

  real :: local_a, local_b
  integer :: local_intsteps

  local_a = a
  local_b = b
  if (present(intsteps)) then
    local_intsteps = intsteps
    integral = Integrate(local_func, a, b, local_intsteps)
  else
    integral = Integrate(local_func, a, b)
  end if
contains
  function local_func(x)
    real, intent(in) :: x
    real :: local_func

    real(c_float) :: local_x

    local_x = x
    local_func = func(local_x)
  end function local_func
end function wrapper_integrate

Note that the presence of optional arguments in an interoperable procedure is a Fortran 2015 feature.

这篇关于关于使用iso_c_binding在C中使用Fortran函数的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

1403页,肝出来的..

09-06 11:22