Я вставляю небольшой пример кода, который вызывает Fortran из C # ниже.Большая проблема, на которой основан этот небольшой воспроизводимый пример, была ранее опубликованной как 32-битная.В последнее время мне нужно, чтобы опубликованный код работал в 64-битном режиме, и именно тогда было обнаружено, что 64-битный код не работает.
Код разрабатывался в Visual Studio с установленным Intel Visual Fortran.Файл .sln содержит 2 проекта - C # в качестве «запускаемого проекта» и проект Intel Visual Fortran, который компилируется в виде DLL и вызывается проектом C #.На странице свойств файла .sln установка «Конфигурация» как 32-битной (x86) работала хорошо.Однако если вместо x64 используется как для C #, так и для Fortran, появляется следующее сообщение об ошибке:
System.DllNotFoundException: «Невозможно загрузить DLL» passStr_Fortran_C.dll ': указанный модуль не найден.(Исключение из HRESULT: 0x8007007E) '
Я надеюсь, что есть флаг или параметр, который просто необходимо переключить?Если это будет сложнее, я надеюсь, что кто-то сможет выложить изменения, которые должны произойти (возможно, с примером проблемы, приведенной ниже)?Вот два кода, которые составляют основу проектов C # и Fortran, которые работают с x86 (win32), но не с x64.
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