【问题标题】:Writing a DLL in Fortran/calling from Excel在 Fortran 中编写 DLL/从 Excel 中调用
【发布时间】:2017-03-31 05:25:14
【问题描述】:

我正在尝试在 Fortran 中编写一些数字功能,以便以后在 Excel 中访问。我正在使用 Office 2013(64 位)、Visual Studio 2015“社区”和英特尔 Fortran(英特尔 Parallel Studio XE 2017);而且我能够正确编译可执行程序。我还能够生成我认为是正确的 DLL 文件。

这是我从this tip 编写的一个最小的 Fortran 代码示例:

function id(x)
    !DEC$ ATTRIBUTES DLLEXPORT :: id
    integer :: id, x
    id = x
    return
end function

我在 Excel 端的 Sheet1 的 VBA 代码下有这个:

Option Explicit
Option Base 1
Public Declare PtrSafe _
    Function id Lib "mydll.dll" _
    (ByVal x As Integer) As Integer

通过这样做,我设法让 Excel 中的公式栏自动完成函数名称,但评估任何实例都会导致单元格短暂闪烁 0,然后变为 #VALUE!。

我在组合/货物崇拜方式中尝试了很多东西:使用 ByRef 而不是 ByVal,让函数仅使用整数或单精度 (real*4) 或双精度 (real*8 ) 浮动,然后是更没有意义的事情。

我终于用完了要混搭的随机键组合,而且很少有资源涵盖这个确切的用例。如果我必须将其归结为比“下一步做什么”更精确的内容:

  • 我遇到问题是因为数字类型还是与 Fortran 和 Excel 世界之间的“阻抗不匹配”相关的问题?
  • 我是否缺少必要的样板、胶水代码等?

【问题讨论】:

    标签: visual-studio fortran excel-addins intel-fortran


    【解决方案1】:

    您似乎不知道英特尔 Fortran 提供了几个连接 Excel/VBA 和 Fortran 的工作示例。从https://software.intel.com/en-us/product-code-samples 下载适用于 Windows 的英特尔 Parallel Studio XE 示例包。在 ZIP 文件中,compiler_f\MixedLanguage\Excel 可能是与您最相关的一个。一个重要的方面是,来自 VBA 的任何调用都需要在被调用例程端指定 STDCALL 调用机制,否则会导致堆栈损坏。

    【讨论】:

    • 在一个更技术性的说明上:有一种叫做 Excel C API 的东西可以用来编写 c/c++ dll 的称为 xll 的,可以在 Excel 中直接引用,其导出的函数可以直接从 Excel 调用,而不像这里那样使用 VBA。这样的事情在 Fortran 中也可能吗?在 C/C++ 方面,代码非常依赖结构和联合(使用指针,这在 Fortran 中是不可能的),因此 Excel 对象模型可能太复杂而无法直接与 fortran 交互。史蒂夫,你知道吗?
    • 我通常的看法是,如果它可以从 C 中调用,那么它可以从 Fortran 中调用。我们正在community.intel.com/t5/Intel-Fortran-Compiler/… 讨论这个问题
    【解决方案2】:

    这是来自 Intel Visual Fortran 帮助文件的 sn-p。

    subroutine FortranCall (r1, num)
        !DEC$ ATTRIBUTES DLLEXPORT, STDCALL, REFERENCE, ALIAS:"FortranCall" :: FortranCall
        integer, intent(in) :: r1
        character(10), intent(out) :: num
        !DEC$ ATTRIBUTES REFERENCE :: num
    
        num = ''
        write (num,'(i0)') r1 * 2
    
    return
    end subroutine FortranCall
    

    在他们使用的 excel 方面:

    Declare Sub FortranCall Lib "C:\Temp\Fcall.dll" (r1 As Long, ByVal num As String)
    

    最好获得更多具有不同输入和输出的示例以帮助用户。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2019-11-30
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-04-14
      相关资源
      最近更新 更多