Я пытаюсь реализовать некоторые уведомления о прогрессе во время трудоемких расчетов в моей библиотеке Фортран. Проблема в том, что AccessViolationException возникает после некоторого времени выполнения, которое зависит от параметров оптимизации моего компилятора (gfortran [-O2 | -O3]). Версия компилятора - 4.5.0.
Вот мой код Fortran:
subroutine arr2par(sarr, w, l, s, progrs )
implicit none
integer w,l, tmp
real*8 sarr(w,l)
real*8 s
integer i,j, k1, k2
interface
integer function progrs(x,y)
integer x,y
end function progrs
end interface
s = 0
do j=1,l
do i=1,w
s = s + sarr(i,j)
k1 = j+i
k2 = w*l
tmp = progrs(k1, k2)
enddo
enddo
end
Вот как это вызывается из C # .NET:
...
try
{
var count = 200;
var count1 = 400;
ProgressReporter reporter = Reporter;
var arr2 = new double[count,count1];
for (int i = 0; i < count; i++)
{
for (int j = 0; j < count1; j++)
{
arr2[i,j] = 1;
}
}
double s;
arr2par_(arr2, ref count, ref count1, out s, reporter);
InsertMessage("Done: "+s);
GC.KeepAlive(arr2);
GC.KeepAlive(reporter);
}
catch (Exception exc)
{
InsertMessage(exc.Message);
}
...
private int Reporter(ref int value, ref int maxValue)
{
Debug.WriteLine(value + "-->" + maxValue);
return 0;
}
private delegate int ProgressReporter(ref int value, ref int maxValue);
[DllImport("test_dll.for.dll")]
private static extern void arr2par_(
Double[,] sarr,
ref Int32 w,
ref Int32 l,
out Double r,
ProgressReporter reporter);
Вот типичный вывод:
2-->80000
3-->80000
4-->80000
5-->80000
6-->80000
7-->80000
89839819-->80000
89839808-->89839812
1785467715-->7935496
89840016-->1895839696
89839840-->11
49145864-->89840092
1785467715-->89839840
0-->0
A first chance exception of type 'System.AccessViolationException' occurred in TestWpfApplication1.exe
Что происходит с адресами? Есть ли лучшая техника?