発生条件は色々なので、上のページから該当しそうなものを確認してください。
ありがちなのは、32bitプログラムから64bitDLL(もしくはその逆)を呼び出しているパターンです。構成マネージャで、プラットフォームを32bitDLLならx86、64bitDLLならx64に合わせましょう。
素人です。
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にすると通る。
発生条件は色々なので、上のページから該当しそうなものを確認してください。
ありがちなのは、32bitプログラムから64bitDLL(もしくはその逆)を呼び出しているパターンです。構成マネージャで、プラットフォームを32bitDLLならx86、64bitDLLならx64に合わせましょう。
@gcotch
QuestionerメニューバーではDebugもReleaseもVBもFORTRANも全て「x64」としています。
(他に設定がなければ)
ありがとうございました。
試しに、呼び出し先で書き換えが発生する引数を、<[In], Out> ByRef としてみてください。
Fortran と VS の組み合わせにもよるのですが、VS のメニューバーで solution の platform を x64 に選んでいても、ドロップダウンメニューから configuration manager を開いてみると、個別の project の platform が x86 になっていることがあリます。確認なされてみては。
@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
@gcotch
QuestionerVBのバージョンがよくわからなかったのですが、ヘルプのMicrosoft Visual Studio についてで、VBの項目はなくMicrosoft Visual Studio Community 2022 (64 ビット) - Current Version 17.10.1です。
変更案は同じ症状でした。(1行で済むのでこっちの方が良いですね)
お時間を取らせすみませんでした。
・「**」を「*」にすると通る。
この時の結果は、正しく110.0
で返るのですね。
だとすると、引数は正しく渡っているということですよね。
Fortranの**
演算子は べき乗 だと思うのですが、$44^{2.5} = 12841.971188256108$で、オーバーフローするような値ではないですし、謎です・・・
@gcotch
QuestionerFORTRAN×BASICというかなり特殊環境ですみませんでした。
そのFortranDLLMulti.dllが依存しているDLLが実は32bitという可能性もあります。
Depenenciesをつかって、依存DLLがすべてAMD64であることを確認してみては。
https://github.com/lucasg/Dependencies
VBがわのEXEが本当にx64なのかは、corflagsに渡せば解ります。
http://tawamuredays.blog.fc2.com/blog-entry-246.html
@gcotch
Questionerありがとうございます。
DLLはAMD64、VBのEXEはx64のようでした。
この方法で実物が確定的に分かるのですね。
(Depenenciesで何が見えているのかさっぱり分かりませんが、libmmd.dll、ext-ms-win-oobe-query-l1-1-0.dllの2項目がN/Aになっているのが気になりますが)
libmmdはintel Fortranコンパイラの数学ライブラリみたいですが、これがN/Aというと、依存DLLが存在しないとか、壊れているとかの話になるような気がしますが、、
DependenciesGuiの画面とか張れません?
https://jp.xlsoft.com/documents/intel/compiler/18/for_18_win_lin/GUID-9526F655-F46D-405B-952E-3FD3F36AA247.html
通常の乗算だとエラーにならず、べき乗だとエラーになるという事は、後者だとFortranのDLL(libmmd)からエクスポートされている関数を呼びにいって、正しいDLLが無いからエラーになってる、みたいなのはありそうですね。