一般来讲,低级语言执行算法的效率高,而高级语言简单易用,尤其是图形用户界面(GUI)这方面很强大。现在的科学工程软件的开发流程一般都是用低级语言做算法,而高级语言做界面。fortran77在科学计算中一直独领风骚,而c#因其易用性以及强大的面向对象的特点备受青睐。
下面显示fortran与c#的交互的基本操作:(编程环境:VS2008(C#+IVF))
1.使用fortran编写dll
这里面我们演示比较麻烦的一种情况,那就是数组的传递。fortran和C系列(C/C++/C#)在数组处理上有2点不同:
(1)fortran数组索引从1开始,而C系列是从0开始。
(2)fortran数组从列开始索引,因为这是物理顺序,执行起来更加高效。即a(1,2)实际上是数组a的第二行第一列元素。所以在fortran中,a(m,n)表示m列n行。做dll很简单,只需要加一些申明即可。
subroutine Arr_Sub (var,row,col)
!DEC$ ATTRIBUTES DLLEXPORT :: Arr_Sub
!DEC$ ATTRIBUTES ALIAS:'Arr_Sub'::Arr_Sub
integer :: row,col
real var(col,row)
integer :: i, j
write(*,*) "Array var received from C# as array is"
write(*,*) var
do i=1,col
do j=1,row
var(i,j)=2.0;
end do
end do
var(1,2)=4.0;
write(*,*) var
end subroutine
其中,!DEC$ ATTRIBUTES DLLEXPORT :: Arr_Sub 表示dll输出函数名称,但因为fortran对大小写不敏感,所以这样申明之后需要用ARR_SUB才可以调用。而!DEC$ ATTRIBUTES ALIAS:’Arr_Sub’::Arr_Sub 表示输出函数对大小写敏感。
2.c#调用fortran编写的dll
这个其实也很简单,只需要加一个[DllImport(...)]和函数的申明即可。
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Runtime.InteropServices; namespace array { class Program { //Example of passing array [DllImport(@"这里是dll文件的路径", CharSet = CharSet.Ansi, CallingConvention = CallingConvention.Cdecl)] public static extern void Arr_Sub(float[,] fArr, ref int row, ref int col); public static void print(float[,] x, int row, int col) { for (int i = 0; i < row; i++) for (int j = 0; j < col; j++) { Console.Write("{0} ", x[i, j]); } } static void Main(string[] args) { float[,] fArr = new float[3, 4]; int row = 3; int col = 4; fArr[1, 2] = 8; print(fArr,row,col); // Call the Fortran subroutine Arr_Sub(fArr, ref row, ref col); print(fArr, row, col); } } }
ctrl+F5,看一下结果吧。
(1)先打印出调用dll之前的数组:0 0 0 0 0 0 8 0 0 0 0 0
(2)然后打印出dll调的结果:
0.0000000E+00 0.0000000E+00 0.0000000E+00 0.0000000E+00 0.0000000E+00
0.0000000E+00 8.000000 0.0000000E+00 0.0000000E+00 0.0000000E+00
0.0000000E+00 0.0000000E+00
(3)再打印dll中改变后的数组:
2.000000 2.000000 2.000000 2.000000 4.000000
2.000000 2.000000 2.000000 2.000000 2.000000
2.000000 2.000000
(4)最后打印c#调用dll后的数组:2 2 2 2 4 2 2 2 2 2 2 2
c#数组的值就这样被修改了。
OK~这个demo做好了(*^__^*)