C#调用Fortran:32位有效,64位无法加载fortran DLL

时间:2019-02-19 17:49:51

标签: c# intel-fortran

我要粘贴一个小的示例代码,该示例代码从下面的C#调用Fortran。这个小的可复制示例所基于的较大问题是previously published(32位)。最近,我需要使已发布的代码在64位上工作,这就是发现64位不起作用的时候。

该代码的开发工作已在Visual Studio中进行,并安装了Intel Visual Fortran。 .sln文件有2个项目-C#作为“启动项目”,以及一个Intel Visual Fortran项目,该项目被编译为DLL并由C#项目调用。在.sln文件的属性页上,将“配置”设置为32位(x86)效果很好。但是,如果在C#和Fortran中同时使用x64,则会出现以下错误消息:

System.DllNotFoundException:'无法加载DLL'passStr_Fortran_C.dll':找不到指定的模块。 (来自HRESULT的异常:0x8007007E)'

我希望有一个仅需要切换的标志或设置?如果比这更复杂,我希望有人可以安排需要进行的修改(也许是下面提供的示例问题)?这是构成与x86(win32)一起使用但不适用于x64的C#和Fortran项目的基础的两个代码。

C#

using System;
using System.Runtime.InteropServices;

public static class Program
{
    public static int Nsegshold;
    public static double[] Diversions = new double[1];
    public static int Process_mode;

    //Fortran DLL interface
    [DllImport("passStr_Fortran_C.dll", CallingConvention = CallingConvention.Cdecl)]  //  CharSet = CharSet.Ansi, 
    public static extern void TEST_Var(ref int Process_mode, ref int Nsegshold, [In, Out] double[] Diversions);

    public static void Main(string[] args)
    {
        Process_mode = 1;
        Nsegshold = 1;
        TEST_Var(ref Process_mode, ref Nsegshold, Diversions);

        // Redimension arrays to size determined in fortran
        Diversions = (double[])ResizeArray(Diversions, new int[] { Nsegshold });

        Process_mode = 2;
        TEST_Var(ref Process_mode, ref Nsegshold, Diversions);

        Console.WriteLine("Two calls to fortran complete. ");
    }

    private static Array ResizeArray(Array arr, int[] newSizes)
    {
        if (newSizes.Length != arr.Rank)
            throw new ArgumentException("arr must have the same number of dimensions " +
                                        "as there are elements in newSizes", "newSizes");

        var temp = Array.CreateInstance(arr.GetType().GetElementType(), newSizes);
        int length = arr.Length <= temp.Length ? arr.Length : temp.Length;
        Array.ConstrainedCopy(arr, 0, temp, 0, length);
        return temp;
    }
}

Fortran

!
    MODULE Fortran_C
!
    CONTAINS
!
    SUBROUTINE TEST_Var(Process_mode, Nsegshold, Diversions) BIND(C,NAME="TEST_Var")
!      
    !DEC$ ATTRIBUTES DLLEXPORT :: TEST_Var
!
    INTEGER, INTENT(IN)             :: Process_mode
    INTEGER, INTENT(INOUT)          :: Nsegshold
    DOUBLE PRECISION, INTENT(INOUT) :: Diversions(Nsegshold)
!
    INTEGER                         :: i
!
    IF(Process_mode.eq.1) THEN
      Nsegshold = 100
    ELSE IF(Process_mode.eq.2) THEN
      DO i = 1, Nsegshold
        Diversions(i) = 3.14 * i
      ENDDO
    ENDIF
!
    END SUBROUTINE TEST_Var
!
    END MODULE Fortran_C

0 个答案:

没有答案