您的位置:首页 > 编程语言 > C#

C#调用FORTRAN编写的DLL

2011-10-24 20:12 197 查看
一般来讲,低级语言执行算法的效率高,而高级语言简单易用,尤其是图形用户界面(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做好了(*^__^*)
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: