使用C#中的模块变量同时调用fortran dll中的方法

时间:2014-05-19 17:27:08

标签: c# fortran pinvoke gfortran

我正在尝试在不同的线程中同时调用Fortran方法。执行完全独立于主线程。问题是使用模块变量意味着变量由dll创建为全局变量,这意味着两个调用将使用它,从而对程序进行instacrash,因此它会发生。这是我的解释,基于此answer of Bálint Aradi

C#

    static void Main(string[] args)
    {
        RunTwiceSync();//WORKS
        RunTwiceAsync();//INSTACRASH
    }

    private static void RunTwiceSync()
    {
        TestMyArray();
        TestMyArray();
    }

    private static void RunTwiceAsync()
    {
        ThreadStart ts = new ThreadStart(() =>
        {
            TestMyArray();
        });
        Thread t = new Thread(ts);
        t.Start();
        TestMyArray();
    }

    private static void TestMyArray()
    {
        Console.WriteLine("START");
        int size = 52;
        float[] myarray = new float[size];
        sub_(ref size, myarray);
        Console.WriteLine(myarray.Select(x => x.ToString()).Aggregate((x, y) => x + ";" + y));
        Console.ReadLine();
    }


    [DllImport("FortranArraySimpleTest.dll", CallingConvention = CallingConvention.Cdecl)]
    static extern void sub_(ref int size, float[] myarray);

FORTRAN

 !DEC$ ATTRIBUTES DLLEXPORT::ingammaextern
subroutine sub(size, myarray)
    use module1   ! * REMOVING MODULE USAGE FIXES THE PROBLEM
  implicit none
INTEGER  :: size
integer :: assignme
REAL, dimension(1:size) :: myarray

assignme = size
allocate(alocarray(1:assignme))
deallocate(alocarray)
end subroutine
! ************************************begin another file***********
      MODULE module1
      IMPLICIT NONE


real, dimension(:), allocatable :: alocarray
      END MODULE module1

这个解决方案,删除模块,是非常麻烦和维护主要的头痛,由于代码使我发布的问题非常大。

环境: GNU Fortran编译器,Windows 7 64位,Fortran的CodeBlocks,VS2012,我没有更改任何编译器选项。

有什么想法吗?

感谢您的时间

1 个答案:

答案 0 :(得分:0)

可以做的是更改派生类型的模块,然后在每次调用时传递

module orig
  use whatever

  interfaces

  small types

  variables

contains

  procedures

end module

module state_class

  use whatever

  interfaces

  small types

  shared variables

  type state
    non shared variables
  contains
    procedure :: the procedures
    (not obligatory)
  end type

contains

  procedures changed to accept one additional argument:
  a passed dummy argument class(state)
  or just a regular dummy argument type(state)

end module

每个线程都有自己的state类实例,并将其显式传递或作为传递的伪参数传递。