//编译 DLL import process.gfortran; //创建 gfortran 编译环境,参数指定工作目录,单个斜杠或反斜杠表示应用程序根目录(工程目录、或工程外独立启动文件所在目录,发布后为 EXE 目录) var fortran = process.gfortran("/"); /* 在工作目录下保存为同名源码文件, 也可以写为 fortran["main.f95"] 显式指定后缀名(可使用 f90,f95,f03 等后缀名)。 Fortran 忽略大小写 Fortran 参数默认是传址的(传指针) Fortran 快速入门: https://learnxinyminutes.com/docs/zh-cn/fortran95-cn/ */ fortran.main = /* module test !引入支持C语言类型的模块,不能写在 DLLEXPORT 后面 https://gcc.gnu.org/onlinedocs/gfortran/ISO_005fC_005fBINDING.html use iso_c_binding !Fortran 2003 特性 type, bind(c) :: POINT integer(c_int) :: x integer(c_int) :: y end type POINT CONTAINS integer function Add (a,b) !声明为 DLL 导出函数,关键是下面这句,调用约定建议用 CDECL,最后面的函数名要一致 !GCC$ ATTRIBUTES CDECL,DLLEXPORT ::Add !Fortran 默认是传址的,所以 integer 实际上是相当于C语言的 int 指针。 integer :: a integer :: b Add = a + b END function integer(c_int) function AddByVal(i,j,d) !GCC$ ATTRIBUTES CDECL,DLLEXPORT ::AddByVal !声明为 DLL 导出函数 !声明为 C语言 int 类型,VALUE 的意思是传值 integer(c_int), VALUE :: i integer(c_int), VALUE :: j real(c_double), VALUE :: d AddByVal = i + j end function integer(c_int) function AddByPoint(pt) !GCC$ ATTRIBUTES CDECL,DLLEXPORT ::AddByPoint type(POINT) :: pt ! Fortran 里用 % 号访问成员(类似 aardio 里的 . 符号) AddByPoint = pt%x + pt%y end function integer(c_int) function hello(str,len) !GCC$ ATTRIBUTES CDECL,DLLEXPORT ::hello CHARACTER*(*) :: str integer(c_int), VALUE :: len !重新绑定控制台 close (unit=6) open(unit=6,file='CONOUT$') !输出字符串 print "(a)",str(1:len) hello = len end function integer function TestArray(arr,len) !GCC$ ATTRIBUTES CDECL,DLLEXPORT ::TestArray integer(c_int), VALUE :: len integer i, arr(len) integer total total = 0 do i = 1,len total = total + arr(i) end do arr(1) = 123 TestArray = total end function end module test */ fortran.buildShared("-o fortran.dll main.f95");