我要粘贴一个小的示例代码,该示例代码从下面的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