Fortran Coder

标题: Dll中可变长度数组作为输出参数的问题 [打印本页]

作者: andy8496    时间: 2017-6-14 12:20
标题: Dll中可变长度数组作为输出参数的问题
先说问题:
实际应用中会遇到这样的问题:读取一个文件获取一些数据。我把这个做成子程序,封装在DLL中,以便不同程序调用。
[Fortran] 纯文本查看 复制代码
subroutine read_data(file_name,num_data,iv_data)
!DEC$ ATTRIBUTES STDCALL,REFERENCE,DLLEXPORT,ALIAS:"read_data"::read_data
implicit none
  character(*),intent(in) :: file_name
  integer,intent(out) :: num_data
  integer,allocatable,intent(out) :: iv_data(:)
! 读取文件,获取数据,得到 num_data,iv_data……
  !代码略
allocate(iv_data(num_data))
iv_data = 88
  return
end subroutine

然后在主程序用调用这个dll中的子程序,获取数据,得到 num_data,iv_data……
[Fortran] 纯文本查看 复制代码
program main
implicit none

  character(256):: file_name
  integer :: num_data
  integer,allocatable :: iv_data()

  file_name = "1.txt"

  call read_data(file_name,num_data,iv_data)
deallocate(iv_data)
  stop
end program

这个时候经常遇到一个问题:程序出错退出了。
以前群主说过,“谁打开,谁关闭;谁声明,谁分配,谁释放”
所以上面这么用就不行,得先得到数据个数,再在主程序中分配好,然后再传给dll中的函数,写起来要麻烦一些。
但是为什么,同样的编译器(IVF),有时候这么用又没有问题?
之前按照上面的示例的方式写了很多这样的dll子程序。现在只能是遇到一个出问题了,改一个,心里始终没底。
这个有没有一个固定的规则?
是不是dll中供外部程序调用的子程序的输出参数就一定不能是变长数组?

还请大家不吝赐教为谢!



作者: li913    时间: 2017-6-14 12:52
“谁打开,谁关闭;谁声明,谁分配,谁释放” 不一定到处都遵守。像你这个情况,如果遵守,就得调用两次dll,没意思。你现在这样写挺好的,至于说出错,那是另一回事。
作者: pasuka    时间: 2017-6-14 13:48
群主的Fortran综合能力已经跻身大陆地区前1%,所以lz大胆怀疑没啥问题,可是小心求证了吗?
1、子程序允许输入未分配的可变长度数组始于哪部Fortran规范呢?当初大佬们讨论的初衷?草案如何演进?
2、其它编译型语言如何实现?C、C++的相关规范、开发建议以及代码实现?
3、gfortran的编译器相关实现代码?或者更简单一点,g95编译器可变长长度数组的C实现代码翻阅了吗?
作者: fcode    时间: 2017-6-14 22:17
如果参数是可分配数组,并且未分配之前传递,则需要“interface”
楼主可以封装在module里,避免手动书写 interface

如果没有interface,则编译器认为该数组是常规数组。可能会出错。




欢迎光临 Fortran Coder (http://bbs.fcode.cn/) Powered by Discuz! X3.2