从Fortran程序中的DLL调用子例程

时间:2017-02-02 13:37:01

标签: dll fortran

我希望在我的研究中使用DLL中的子程序。 dll作为黑盒子提供给我,可用于领先的有限元软件。

我为dll执行了以下代码

dumpbin /EXPORTS UDSM_HPS.dll > UDSM_HPS.exports

并最终得到以下子程序

2    0 00020D50 _getmodelcount@4
4    1 00020D60 _getmodelname@12
6    2 00020E50 _getparamcount@8
8    3 00020E80 _getparamname@16
10    4 00021AE0 _getparamunit@16
12    5 00001010 _user_mod@124
1    6 00020D50 getmodelcount
3    7 00020D60 getmodelname
5    8 00020E50 getparamcount
7    9 00020E80 getparamname
9    A 00021AE0 getparamunit
11    B 00001010 user_mod

我的兴趣在于' user_mod '子例程。我在.def文件中创建了一个.lib文件,在文件开头添加'EXPORTS'并使用以下代码隔离子例程名称

lib /def:UDSM_HPS.def /out:UDSM_HPS.lib

并将.lib文件附加到我的Visual Studio 2013的'Resourse Files',同时将我的.dll副本放到我的'Debug'文件夹中。

这里没有惊喜,编译器看不到'user_mod'子程序。

现在我的问题是,我错过了什么,或者是否有不同的方法来利用dll中的子程序?

dll也是用FORTRAN编写的,我在FORTRAN中编写了一段简单的FE代码来运行这个子程序。

长话短说:任何帮助都是如何在FORTRAN程序中找到如何使用FORTRAN dll非常感谢。

修改1:

我正在使用英特尔Fortran编译器 - 英特尔(R)Visual Fortran编译器XE 15.0.6.285 [IA-32]。我曾尝试在英特尔(R)Fortran编译器10.1.021 [IA-32]中编译相同的代码,但是徒劳无功。

我打算调用的子程序是

call user_mod(IDTask, iMod, IsUndr, iStep, iTer,& 
    iEl, Int, X, Y, Z, Time0, dTime, Props, Sig0, Swp0, StVar0,& 
    dEps, D, BulkW, Sig, Swp, StVar, ipl, nStat, NonSym, iStrsDep,&
    iTimeDep, iTang, iAbort)

为了澄清我的相当模糊的句子“编译器没有看到”,我的意思是这个错误

  

错误1错误LNK2019:函数PLAXIS_DLL_INTF中引用的未解析的外部符号USER_MOD interface_files.obj

编辑2: 感谢所有的帮助。 添加

!DEC$ ATTRIBUTES STDCALL,REFERENCE :: USER_MOD

只需要我的代码就可以了。代码的行为就像它现在应该的样子。

1 个答案:

答案 0 :(得分:1)

感谢您提供错误消息 - 这是关键。编译器不能看到user_mod,它是链接器。请注意,错误消息引用USER_MOD,但您对符号的转储表示user_mod。案件很重要!

您正在调用的例程具有STDCALL调用机制也很重要。这不是英特尔Fortran的默认设置,如果出现这种错误会导致堆栈损坏。

解决方案是添加以下行:

import Foundation
import UIKit

class Settings: UIView {

let defaults = UserDefaults.standard

let durationSlide = "durationSlide"


@IBOutlet weak var durationSlider: UISlider!
@IBOutlet weak var durationLabel: UILabel!

func viewDidLoad() {

    if let durationSlide = defaults.value(forKey: durationSlide) {
        durationSlider.value = durationSlide as! Float
        durationSliderValueChanged(durationSlider)
    }


}


@IBAction func durationSliderValueChanged(_ sender: UISlider) {
    let currentValue = Int(sender.value)
    durationLabel.text = "\(currentValue) minutes"
    defaults.set(sender.value, forKey: durationSlide)
}

调用USER_MOD的例程 - 使用声明。这告诉英特尔Fortran,USERMOD是一个STDCALL例程,并对例程名称进行了下调。当您调用USER_MOD时,还要确保传递正确的参数数量和类型。如果你弄错了,你会收到链接错误。最后,我在这里猜测REFERENCE的使用,但我认为它是正确的,因为我不知道USER_MOD是如何构建的。至少这会让你超过链接错误。