VB呼び出しFortranの簡単な例を試してみると、どのアプローチを取ろうとしているかによって2つのエラーが発生しています。下記の小さな再現可能な例は簡単ですが、はるかに大きな問題の前駆体です。VB.NETのFortran呼び出し:PInvoke例外を修正する方法は?
この簡単な例の主な目的は、Fortranコード(この場合は「SUMMATION」)に渡される引数の値を調整し、VBで返された(調整済みの)値を使用することです。私が最初にエラーメッセージと共に各アプローチの結果を、それを呼び出すために使用VBコードの2つのバリエーションを示し、その後、単純なFortranコードを提供
VBによって呼び出さFortranコード:
SUBROUTINE MFNWT_RUN(KSTP,KPER,SUMMATION)
!DEC$ ATTRIBUTES DLLEXPORT :: MFNWT_RUN
!DEC$ ATTRIBUTES ALIAS: "MFNWT_RUN" :: MFNWT_RUN
IMPLICIT NONE
INTEGER, Intent(in) :: KPER, KSTP
INTEGER, Intent(inout) :: SUMMATION
INTEGER kkper, kkstp
INTEGER add_em_up
kkper = KPER
kkstp = KSTP
add_em_up = kkper + kkstp
SUMMATION = add_em_up
END SUBROUTINE
呼び出すVBコード(最初のアプローチ):
Imports System.Collections
Imports System
Imports System.Runtime.InteropServices
Imports System.IO
Imports System.Data
Module Module1
<DllImport("example_fortran_directory.dll", CallingConvention:=CallingConvention.StdCall)>
Public Function MFNWT_RUN(ByVal a As Integer, ByVal b As Integer, ByRef Divs As Integer) 'ref bool AdvFlwRdr
End Function
' Private Declare Sub MFNWT_RUN Lib "example_fortran_directory.dll" Alias "MFNWT_RUN" (<[In](), Out()> ByRef A As Integer, ByRef B As Integer, ByRef C As Integer)
'Declare Sub MFNWT_RUN Lib "example_fortran_directory" (ByRef A As Integer, ByRef B As Integer, ByRef C As Integer)
Sub Main()
Dim first As Integer
Dim second As Integer
Dim answer As Integer
first = 6
second = 7
answer = 0
Call MFNWT_RUN(first, second, answer)
MsgBox(answer)
End Sub
End Module
がエラーを与える:
私がしようとすると「ワイヤーアップ」少し異なるFortranのDLLの呼び出し(DLLIMPORTコードをコメントアウトし、宣言コードのコメントを解除)の代わりにした場合、私は別の取得しますエラー。
呼び出すVBコード(第二のアプローチ):
Imports System.Collections
Imports System
Imports System.Runtime.InteropServices
Imports System.IO
Imports System.Data
Module Module1
' Private Declare Sub MFNWT_RUN Lib "example_fortran_directory.dll" Alias "MFNWT_RUN" (<[In](), Out()> ByRef A As Integer, ByRef B As Integer, ByRef C As Integer)
Declare Sub MFNWT_RUN Lib "example_fortran_directory" (ByRef A As Integer, ByRef B As Integer, ByRef C As Integer)
Sub Main()
Dim first As Integer
Dim second As Integer
Dim answer As Integer
first = 6
second = 7
answer = 0
Call MFNWT_RUN(first, second, answer)
MsgBox(answer)
End Sub
End Module
は、次の例外を提供します:
この第二のアプローチは動作します - 私は誤りを認めた場合、私は移動することができることを意味し過去の問題を解決する方法を教えてください。私が取り組もうとしているより大きな問題は、VBからFortranに何千もの呼び出しを行うことになるので、スタックの不均衡エラーを正しい方法で修正することが重要であるように思えます(警告メッセージを消すだけではありません)。
また、PInvokeStackImbalanceエラーが発生した別の試みを追加します。
まずFORTRAN:
SUBROUTINE MFNWT_RUN(KSTP,KPER,SUMMATION)
!DEC$ ATTRIBUTES DLLEXPORT, ALIAS: 'MFNWT_RUN' :: MFNWT_RUN
!DEC$ ATTRIBUTES REFERENCE :: KSTP
!DEC$ ATTRIBUTES REFERENCE :: KPER
!DEC$ ATTRIBUTES REFERENCE :: SUMMATION
IMPLICIT NONE
INTEGER, value :: KPER, KSTP
INTEGER, value :: SUMMATION
INTEGER kkper, kkstp
INTEGER add_em_up
kkper = KPER
kkstp = KSTP
add_em_up = kkper + kkstp
SUMMATION = add_em_up
END SUBROUTINE MFNWT_RUN
、呼び出しVB:
Imports System.Collections
Imports System
Imports System.Runtime.InteropServices
Imports System.IO
Imports System.Data
Module Module1
Private Declare Sub MFNWT_RUN Lib "example_fortran_directory.dll" Alias "MFNWT_RUN" (<[In](), Out()> ByRef A As Integer, ByRef B As Integer, ByRef C As Integer)
Sub Main()
Dim first As Integer
Dim second As Integer
Dim answer As Integer
first = 6
second = 7
answer = 0
Call MFNWT_RUN(first, second, answer)
MsgBox(answer)
End Sub
End Module
このアプローチは、スローされPInvokeStackImbalance例外に終わりました。最初に、この例外が大きな問題であるかどうかを疑問に思っています(つまり、この例外がスローされたときに、コードを移動して暖かいことを意味する)。もしそれが修正されるべきであるなら(私はこれが事実であると仮定します)、あなたは私の問題が何であるかを見て、助けてください。
Private Declare Sub MFNWT_RUN Lib "example_fortran_directory.dll" Alias "MFNWT_RUN" (<[In](), Out()> ByRef A As Integer, ByRef B As Integer, ByRef C As Integer)
は常に言及:
は、以前私が動作するように、他のアプローチを得ることができなかった代わりに
Public Sub...
の
Public Function...
を持っていた: –Fortranサブルーチンを 'INTEGER、Intent(in)、value :: KPER、KSTP'に変更すると、改善されますか? – francescalus
値は 'bind(C)'を伴います。 –