使用 Fortran Dll 的托管代码回调时出现 AccessViolationException
我正在尝试在 Fortran dll 中的耗时计算过程中实现一些进度通知。问题是,执行一段时间后会引发 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
地址怎么了?有没有更好的技术?
I'm trying to implement some progress notification during time-consuming calculation in my Fortran dll. The problem is that AccessViolationException is raised after some time of execution that depends on optimization options of my compiler (gfortran [-O2|-O3]) Version of compiler - 4.5.0.
Here is my fortran code:
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
Here is how it is invoked from 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);
Here is typical output:
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
What's going on with addresses? Is there any better technique?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论