gcotch
@gcotch

Are you sure you want to delete the question?

If your question is resolved, you may close it.

Leaving a resolved question undeleted may help others!

We hope you find it useful!

Fortranで作成したDLL参照で間違ったフォーマットのエラー

解決したいこと

素人です。
VBからFortranで作成したDLLを参照するとエラーが生じます。
VB側からデバックした場合に生じます。(VB:Debug、DLL:Release)
どうやらべき乗の指数に引数を充てるとなるようなのですが。
すみません素人考えです。解決方法はどういったものが考えられるでしょうか?
VisualStudio2022、IntelFortranCompiler2024.1を統合した環境

発生している問題・エラー

ハンドルされてない例外

System.BadImageFormatException: '間違ったフォーマットのプログラムを読み込もうとしました。 (HRESULT からの例外:0x8007000B)'

下記コードのCall FORTRAN_EXTERNAL(A, B)で発生

該当するソースコード

Public Class Form1
Declare Sub FORTRAN_EXTERNAL Lib "・・・\x64\Release\FortranDLLMulti.dll" _
                 (ByRef A As Double, ByRef B As Double)
Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
  Dim A As Double = 44
  Dim B As Double = 2.5
  Call FORTRAN_EXTERNAL(A, B)
End Sub
End Class

module FortranDLLMulti
implicit none
contains
SUBROUTINE FORTRAN_EXTERNAL(A, B)
  !DEC$ ATTRIBUTES DLLEXPORT :: FORTRAN_EXTERNAL
  !DEC$ ATTRIBUTES ALIAS : "FORTRAN_EXTERNAL" :: FORTRAN_EXTERNAL
  implicit none
  real(8), intent(inout) :: A
  real(8), intent(inout) :: B
  A = A ** B
END SUBROUTINE
end module FortranDLLMulti

自分で試したこと

・「**」を「*」にすると通る。
・DLL側からのデバックでは通る。
・A**BのBを直接数値2.5にしたり、別途用意した変数C=2.5にすると通る。

0

3Answer

発生条件は色々なので、上のページから該当しそうなものを確認してください。
ありがちなのは、32bitプログラムから64bitDLL(もしくはその逆)を呼び出しているパターンです。構成マネージャで、プラットフォームを32bitDLLならx86、64bitDLLならx64に合わせましょう。

0Like

Comments

  1. @gcotch

    Questioner

    メニューバーではDebugもReleaseもVBもFORTRANも全て「x64」としています。
    (他に設定がなければ)
    ありがとうございました。

  2. 試しに、呼び出し先で書き換えが発生する引数を、<[In], Out> ByRef としてみてください。

  3. Fortran と VS の組み合わせにもよるのですが、VS のメニューバーで solution の platform を x64 に選んでいても、ドロップダウンメニューから configuration manager を開いてみると、個別の project の platform が x86 になっていることがあリます。確認なされてみては。

  4. @gcotch

    Questioner

    <[In], Out> ByRef は real(8), intent(inout) :: A でやってるつもりですが。
    !DEC$ ATTRIBUTES REFERENCE :: A を追加してみたりもしましたが変わらずでした。
    ありがとうございました。

    x64はconfiguration managerの中も全x64でした。

VBのバージョンは、Visual Basic 2019(VB16)でしょうか?

以下のように変更すると、どうでしょうか?
(変わらないかも)

- !DEC$ ATTRIBUTES DLLEXPORT :: FORTRAN_EXTERNAL
- !DEC$ ATTRIBUTES ALIAS : "FORTRAN_EXTERNAL" :: FORTRAN_EXTERNAL

+ !DEC$ ATTRIBUTES DLLEXPORT, ALIAS : "FORTRAN_EXTERNAL" :: FORTRAN_EXTERNAL
0Like

Comments

  1. @gcotch

    Questioner

    VBのバージョンがよくわからなかったのですが、ヘルプのMicrosoft Visual Studio についてで、VBの項目はなくMicrosoft Visual Studio Community 2022 (64 ビット) - Current Version 17.10.1です。

    変更案は同じ症状でした。(1行で済むのでこっちの方が良いですね)

    お時間を取らせすみませんでした。

  2. ・「**」を「*」にすると通る。

    この時の結果は、正しく110.0で返るのですね。
    だとすると、引数は正しく渡っているということですよね。

    Fortranの**演算子は べき乗 だと思うのですが、$44^{2.5} = 12841.971188256108$で、オーバーフローするような値ではないですし、謎です・・・

  3. @gcotch

    Questioner

    FORTRAN×BASICというかなり特殊環境ですみませんでした。

Comments

  1. @gcotch

    Questioner

    ありがとうございます。
    DLLはAMD64、VBのEXEはx64のようでした。
    この方法で実物が確定的に分かるのですね。
    (Depenenciesで何が見えているのかさっぱり分かりませんが、libmmd.dll、ext-ms-win-oobe-query-l1-1-0.dllの2項目がN/Aになっているのが気になりますが)

  2. 通常の乗算だとエラーにならず、べき乗だとエラーになるという事は、後者だとFortranのDLL(libmmd)からエクスポートされている関数を呼びにいって、正しいDLLが無いからエラーになってる、みたいなのはありそうですね。

Your answer might help someone💌