使用多变量函数时出现 Fortran DLL 错误
Fortran DLL error when using a multivariable function
我目前正在开发一个 fortran DLL,但我对多变量函数有疑问。我的最终 objective 是
- 从 VBA
调用 DLL 函数
- 使用调用 DLL 函数的 Fortran 代码调试 DLL
这是我的简化案例:
1. Fortran DLL 代码
module mod_thermo
implicit none
contains
function y1(x1) result(y) bind(c, name = "Y1")
use iso_c_binding, only : c_double
!GCC$ attributes dllexport, stdcall :: y1
real(c_double) :: x1
real(c_double) :: y
y = 2.d0 * x1
end function
function y2(x1, x2) result(y) bind(c, name = "Y2")
use iso_c_binding, only : c_double
!GCC$ attributes dllexport, stdcall :: y2
real(c_double) :: x1
real(c_double) :: x2
real(c_double) :: y
y = 2.d0 * x1 * x2
end function
end module
2。使用 GCC
的 Fortran DLL 编译选项
编译器是 GCC。编译选项是:
- -static(避免依赖于其他 dll)
- -Wl,--kill-at (VBA 相关)
- -fno-下划线(VBA相关)
输出文件位于 fortran 代码的项目文件夹中以供将来调试:
- dll_thermo.dll
- libdll_thermo.a
- libdll_thermo.def
3。 DLL测试的Fortran代码(接口+程序)
DLL通过点赞库链接到代码libdll_thermo.a
module mod_thermo
implicit none
interface
function y1(x1) result(y) bind(c,name="Y1")
use iso_c_binding, only : c_double
real(c_double) :: x1
real(c_double) :: y
end function
function y2(x1, x2) result(y) bind(c,name="Y2")
use iso_c_binding, only : c_double
real(c_double) :: x1
real(c_double) :: x2
real(c_double) :: y
end function
end interface
end module
program main
use mod_thermo
implicit none
write(*,*)"y1 calls:"
write(*,*)y1(1.d0) ! output ok
write(*,*)y1(2.d0) ! output ok
write(*,*)y1(3.d0) ! output ok
write(*,*)"y2 calls:"
write(*,*)y2(1.d0, 1.d0) ! output ok
write(*,*)y2(2.d0, 2.d0) ! output fails
write(*,*)y2(3.d0, 2.d0)
end program
4.输出和结论
我的结论是我没有以正确的方式执行多变量 DLL 函数 y2 调用。您执行此类调用的方式是什么?
问题来自 link 到 "libdll_thermo.a"。根据 here 的教程,我发现我应该 linked "libdll_thermo.dll"。现在可以了。
我目前正在开发一个 fortran DLL,但我对多变量函数有疑问。我的最终 objective 是
- 从 VBA 调用 DLL 函数
- 使用调用 DLL 函数的 Fortran 代码调试 DLL
这是我的简化案例:
1. Fortran DLL 代码
module mod_thermo
implicit none
contains
function y1(x1) result(y) bind(c, name = "Y1")
use iso_c_binding, only : c_double
!GCC$ attributes dllexport, stdcall :: y1
real(c_double) :: x1
real(c_double) :: y
y = 2.d0 * x1
end function
function y2(x1, x2) result(y) bind(c, name = "Y2")
use iso_c_binding, only : c_double
!GCC$ attributes dllexport, stdcall :: y2
real(c_double) :: x1
real(c_double) :: x2
real(c_double) :: y
y = 2.d0 * x1 * x2
end function
end module
2。使用 GCC
的 Fortran DLL 编译选项编译器是 GCC。编译选项是:
- -static(避免依赖于其他 dll)
- -Wl,--kill-at (VBA 相关)
- -fno-下划线(VBA相关)
输出文件位于 fortran 代码的项目文件夹中以供将来调试:
- dll_thermo.dll
- libdll_thermo.a
- libdll_thermo.def
3。 DLL测试的Fortran代码(接口+程序)
DLL通过点赞库链接到代码libdll_thermo.a
module mod_thermo
implicit none
interface
function y1(x1) result(y) bind(c,name="Y1")
use iso_c_binding, only : c_double
real(c_double) :: x1
real(c_double) :: y
end function
function y2(x1, x2) result(y) bind(c,name="Y2")
use iso_c_binding, only : c_double
real(c_double) :: x1
real(c_double) :: x2
real(c_double) :: y
end function
end interface
end module
program main
use mod_thermo
implicit none
write(*,*)"y1 calls:"
write(*,*)y1(1.d0) ! output ok
write(*,*)y1(2.d0) ! output ok
write(*,*)y1(3.d0) ! output ok
write(*,*)"y2 calls:"
write(*,*)y2(1.d0, 1.d0) ! output ok
write(*,*)y2(2.d0, 2.d0) ! output fails
write(*,*)y2(3.d0, 2.d0)
end program
4.输出和结论
我的结论是我没有以正确的方式执行多变量 DLL 函数 y2 调用。您执行此类调用的方式是什么?
问题来自 link 到 "libdll_thermo.a"。根据 here 的教程,我发现我应该 linked "libdll_thermo.dll"。现在可以了。