Visual c++ 关于在C语言中使用Fortran函数与iso_C_绑定
我花了几天时间学习Fortran的C互操作性,以便从C调用Fortran函数DLL。 我在这里找到了这个链接: 我尝试像这样创建Fortran DLL,我的编译器是“英特尔Fortran编译器”:Visual c++ 关于在C语言中使用Fortran函数与iso_C_绑定,visual-c++,fortran,intel-fortran,fortran-iso-c-binding,Visual C++,Fortran,Intel Fortran,Fortran Iso C Binding,我花了几天时间学习Fortran的C互操作性,以便从C调用Fortran函数DLL。 我在这里找到了这个链接: 我尝试像这样创建Fortran DLL,我的编译器是“英特尔Fortran编译器”: module integration implicit none contains function Integrate(func, a,b, intsteps) result(integral) !DEC$ ATTRIBUTES DLLEXPORT :: Integrate i
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
代码中表示的错误行,看起来好像myfunc
不等于模块集成中定义的func
。也许我可以使用iso\u c\u绑定
来修改模块集成
有时一些Fortran函数中有许多参数需要分配和使用,在Fortran中使用
iso_c_binding
并不容易。那么如何解决MYFUNC
中的错误呢?如果一个伪过程有一个显式的接口,那么它的特性必须与实际过程的特性相同,除了一些与此无关的东西
过程的特征包括它是否具有BIND属性
为了使特性一致,您可以使用一个没有BIND(C)的小中间过程来调用您提供的BIND(C)过程
例如,通过一些其他更改,以避免关于c_float和c_int是否指定默认实数和整数类型的假设:
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
请注意,可互操作过程中存在可选参数是Fortran 2015的一项功能。集成中的虚拟过程具有
bind
属性;作为实际参数的函数指针myfunc
具有给定的接口iFunc
,该接口没有bind
接口。是!我忘了!现在我可以导出Fortran Dll了。谢谢你编辑我的问题,让它变得简洁!谢谢我需要检查一下!顺便说一下,可以在.NET Framework中调用英特尔Fortran?bind(C,name='integrate')应该是bind(C,name='wrapper_integrate'),它可以工作!这个方法对我很有帮助。绑定标签的名称取决于你所称的C函数。那么,如果我想把数组传递给local_func?怎么做?
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