Я создаю консольный проект С# net4.5, который потребляет fortran dll. Метод из этой DLL отлично работает при первом вызове и instacrashes во втором вызове, никаких сообщений об ошибках любого типа.
Запустив некоторые тесты, я обнаружил, что если я не буду использовать модуль 1, то есть поставить объявление переменной в подпрограмму, он отлично работает на любом количестве вызовов
С#
static void Main(string[] args)
{
TestMyArray();//WORKS FLAWLESLY
TestMyArray();//INSTAKILLS PROGRAM
}
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))
end subroutine
! ************************************begin another file***********
MODULE module1
IMPLICIT NONE
real, dimension(:), allocatable :: alocarray
END MODULE module1
Это решение, удаление модулей, является чрезвычайно громоздким и основной головной болью обслуживания, благодаря коду, который заставил меня поставить вопрос очень большой.
Окружающая среда: компилятор GNU Fortran, Windows 7 64bits, CodeBlocks for fortran, VS2012, я не изменял никаких параметров компилятора.
Есть идеи?
Спасибо за ваше время
Вы должны освободить массив allocarray
в подпрограмме, прежде чем покинуть его. Поскольку это модульная переменная, используемая ассоциацией хоста в вашей подпрограмме, она останется выделенной после того, как будет оставлена подпрограмма. Попытка выделить его снова, когда вы входите в процедуру, второй раз может стать причиной вашего сбоя. Кроме того, вы можете проверить его статус распределения с помощью встроенной функции allocated()
.