0

私は Fortan の初心者で、コールバック関数を fortran コード全体で使用できるようにすることについて質問があります。

C# から Fortran DLL にアクセスするインターフェイスについて書いています。

module csWrapper
  interface
    subroutine vdiTestFuncCllBak(inputValue, retValue)
      INTEGER, INTENT(IN) :: inputValue
      INTEGER, INTENT(INOUT) :: retValue      
    end subroutine
  end interface

  procedure(vdiTestFuncCllBak), pointer :: m_vdiTestFuncCllBak
end module csWrapper

module VdiFunctionRunnerMain
  use csWrapper
  implicit none

  contains       
    integer function VdiFunctionRunner (XTGA, ARRAY_810, vdiCwertCllbak, vdiIwertCllbak, vdiRwertCllbak, vdiCwert2Cllbak, vdiIwert2Cllbak, vdiRwert2Cllbak, vdiErsterCllBak, vdiLetzterCllBak, vdiTestFuncCllBak)
      !DEC$ ATTRIBUTES DLLEXPORT ::VdiFunctionRunner
      !DEC$ ATTRIBUTES REFERENCE :: XTGA, ARRAY_810, vdiCwertCllbak, vdiIwertCllbak, vdiRwertCllbak, vdiCwert2Cllbak, vdiIwert2Cllbak, vdiRwert2Cllbak, vdiErsterCllBak, vdiLetzterCllBak, vdiTestFuncCllBak
      implicit none      
      external vdiCwertCllbak, vdiIwertCllbak, vdiRwertCllbak, vdiCwert2Cllbak, vdiIwert2Cllbak, vdiRwert2Cllbak, vdiErsterCllBak, vdiLetzterCllBak, vdiTestFuncCllBak

      !procedure(vdiErsterCllBak), pointer :: m_vdiErsterCllBak
      CHARACTER (len=256) XTGA
      CHARACTER (len=256) TGA, ARRAY_810(10), retValue, satzArt, satzArt2
      CHARACTER (len=256) :: cWertCallBackRet

      integer :: nrReturnValues = 1

      m_vdiTestFuncCllBak => vdiTestFuncCllBak

      call vdiTestFuncCllBak(nrReturnValues, nrReturnValues)
      call m_vdiTestFuncCllBak(1, nrReturnValues)

      VdiFunctionRunner = nrReturnValues
    end function VdiFunctionRunner

end module VdiFunctionRunnerMain

Fortran コードは C# コードのいくつかの関数を使用する可能性を必要とするため、2 つのデリゲートを Fortran コードに渡します (vdiCwertCllbak、vdiIwertCllbak)。

これは、MainFunction で使用すると非常にうまく機能するため、インターフェイスはこれまでのところ機能しています。

ここで必要なのは、c# 関数が MainFunction の外部の他の関数から、さらには別のモジュールからも利用できる必要があることです。

この問題に対処するために関数ポインタを使用しようとしましたが、m_vdiTestFuncCllBak を呼び出すと常に次のエラーが発生します。vdiTestFuncCllBak の呼び出しは問題なく機能します。

関数内または外部モジュール内でポインターを初期化する場合と同じ動作です。

次の c# コードが呼び出されます。

private void vdiTestFunc(ref int inputValue, ref int retValue)
{
  retValue = inputValue + 1;
  return;
}

問題は、functionpointer を使用するときに、inputValue と retValue の参照が設定されていないことです。

誰かが以前に同じ問題を抱えていて、可能な解決策を知っているか、ヘルプへのリンクを持っていますか? 私の検索では、それに関する情報は見つかりませんでした。

Intel 11 コンパイラを使用しています。

助けていただければ幸いです。

4

1 に答える 1

2

手っ取り早い汚い方法は、プロシージャ ポインタを含むモジュールを作成することです。

module callback_module
    procedure(),pointer::p
end module

integer function MainFunction(XTGA, ARRAY_810, vdiCwertCllbak, vdiIwertCllbak)
  !DEC$ ATTRIBUTES DLLEXPORT ::MainFunction
  !DEC$ ATTRIBUTES REFERENCE :: XTGA, ARRAY_810, vdiCwertCllbak, vdiIwertCllbak
  use callback_module
  implicit none

  external vdiCwertCllbak, vdiIwertCllbak
  integer :: nrReturnValues = 1
  integer :: iWertCallBackRet = 12
  satzArt = '710.10' // char(0)

  p=>vdiIwertCllbak
  call vdiIwertCllbak(satzArt, 1, 2, iWertCallBackRet)

  MainFunction= nrReturnValues
end function MainFunction

integer function tga_810(xtga,array_810)  
  use callback_module
  character(len=256) xtga,tga,array_810(4),s, caption, inputBox

  call p('710' // char(0), 1, 2, retValue)

  tga_810 = 1
end function tga_810

編集:

アクセス違反は、ポインターに関連付けられたインターフェイスがないことが原因である可能性があります。

module callback_module
    interface
        subroutine callback_sub(arg1,arg2,...)
            !Declare all arguments as they appear in the actual callback routine
        end subroutine
    end interface

    procedure(callback_sub),pointer::p
end module

インターフェイスのプロシージャ引数を正しく定義する必要があります。

また、オプションの引数が原因である可能性もあります。vdiIwertCllbak にはオプションがありますか?

于 2011-10-24T21:29:12.263 に答える