使Fortran中的其他功能/模块可以访问外部函数

时间:2011-10-24 08:29:40

标签: interface fortran95

我是Fortan的新手,并且有一个关于使用make callback-functions可用于整个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#代码的某些函数,所以将两个代理传递给Fortran代码(vdiCwertCllbak,vdiIwertCllbak)。

当它们在MainFunction中使用时,它的效果非常好,因此到目前为止接口工作正常。

现在需要的是,c#函数必须可以从MainFunction以外的其他函数中获得,甚至可以在不同的模块中使用。

我尝试使用functionpointers来处理这个问题,但在调用m_vdiTestFuncCllBak时总是会出现以下错误。调用vdiTestFuncCllBak没有问题。

在函数或外部模块中初始化指针时,它的行为相同。

调用以下c#代码:

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

问题是,使用funtionpointer时没有设置inputValue和retValue的引用。

之前是否有人遇到过同样的问题并且知道可能的解决方案或者有帮助链接?我在搜索中没有找到相关信息。

我正在使用Intel 11编译器。

非常感谢帮助。

1 个答案:

答案 0 :(得分: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有选项吗?