C#与Fortran混合编程本地调用Fortran动态链接库.docx

上传人:b****6 文档编号:8726284 上传时间:2023-02-01 格式:DOCX 页数:11 大小:477.56KB
下载 相关 举报
C#与Fortran混合编程本地调用Fortran动态链接库.docx_第1页
第1页 / 共11页
C#与Fortran混合编程本地调用Fortran动态链接库.docx_第2页
第2页 / 共11页
C#与Fortran混合编程本地调用Fortran动态链接库.docx_第3页
第3页 / 共11页
C#与Fortran混合编程本地调用Fortran动态链接库.docx_第4页
第4页 / 共11页
C#与Fortran混合编程本地调用Fortran动态链接库.docx_第5页
第5页 / 共11页
点击查看更多>>
下载资源
资源描述

C#与Fortran混合编程本地调用Fortran动态链接库.docx

《C#与Fortran混合编程本地调用Fortran动态链接库.docx》由会员分享,可在线阅读,更多相关《C#与Fortran混合编程本地调用Fortran动态链接库.docx(11页珍藏版)》请在冰豆网上搜索。

C#与Fortran混合编程本地调用Fortran动态链接库.docx

C#与Fortran混合编程本地调用Fortran动态链接库

C#与Fortran混合编程-本地调用Fortran动态链接库

Fortran是一门古老的语言,它是世界上最早出现的计算机高级程序设计语言,广泛应用于科学和工程计算领域。

FORTRAN语言以其特有的功能在数值、科学和工程计算领域发挥着重要作用。

然而Fortran程序本身不适合开发独立的应用程序,例如我们传统的桌面应用或者Web应用。

因此这里我们便想将C#与Fortran结合,C#借助Fortran可以实现精度更高,计算更快的程序,而Fortran通过C#,便也能够达到可视化设计。

 

一、基本思路

运用Fortran,编写动态链接库(DLL),在DLL中提供计算的函数接口,然后在C#中调用该DLL中计算部分的函数,实现计算过程。

这里需要注意的是,由于我们使用的是Fortran编译器,生成的DLL属于第三方非托管DLL,因此无法直接在程序中添加DLL的引用。

具体的做法将在后续部分说明。

 

二、编写Fortran程序,生成动态链接库文件

知道思路之后便开始正式的Coding。

首先新建一个空的FortranDynamic-linkLibrary项目。

在Intel(R)VisualFortran点击Library,选中右图的Dynamic-linkLibrary.然后点击OK.这时的项目如下所示:

点击SourcesFile文件夹,选择新建项。

添加一个新的Fortran文件

然后便开始Fortran代码的编写工作。

这里我们主要实现两个方法:

一个方法是求两个数相加之和,并返回结果。

另一个是输入一个数组,对这个数组进行排序,并找出最大值,最后返回排序后的结果,并返回最大值。

这里我们分别演示的是Fortran传出一个数和一个数组有何不同。

关于Fortran的基本语法不是本文的讨论范畴,请读者自行查阅资料。

下面给出的上述我们要实现的功能的具体Fortran代码:

DOUBLEPRECISIONFUNCTIONADD(A,B)

!

DEC$ATTRIBUTESDLLEXPORT:

:

ADD

!

DEC$ATTRIBUTESSTDCALL,ALIAS:

'Add':

:

ADD

DOUBLEPRECISION:

:

A,B

ADD=A+B

END

FUNCTIONSORTANDFINDMAX(ARRAY,LENGTH)

!

DEC$ATTRIBUTESDLLEXPORT:

:

SORTANDFINDMAX

!

DEC$ATTRIBUTESSTDCALL,ALIAS:

'Sortandfindmax':

:

SORTANDFINDMAX

DOUBLEPRECISION:

:

ARRAY(LENGTH)

INTEGER:

:

I,J

DOUBLEPRECISION:

:

SORTANDFINDMAX,TEMP

SORTANDFINDMAX=ARRAY

(1)

DOI=1,LENGTH-1

DOJ=I+1,LENGTH

IF(ARRAY(I).GT.ARRAY(J))THEN

TEMP=ARRAY(I)

ARRAY(I)=ARRAY(J)

ARRAY(J)=TEMP

SORTANDFINDMAX=ARRAY(J)

ENDIF

ENDDO

ENDDO

END

上面我们声明了两个Fortran函数,一个是计算两个数相加,一个是选择排序并找出最大值。

之后我们点击VisualStudio的BuildSolution.开始编译成DLL。

关于代码段解释:

!

DEC$ATTRIBUTESDLLEXPORT:

:

ADD

!

DEC$ATTRIBUTESSTDCALL,ALIAS:

'Add':

:

ADD

这两句代码很关键。

下面通过三个一致来简单的说一下以上代码段的意思和C#调用需要注意的问题。

1.函数名一致:

在Fortran编译器中默认的导出函数名全部是大写形式。

而在C#中调用FortranDll时必须指定函数名一致。

在Fortran方面解决的办法是:

使用ALIAS(别名)属性指定导出函数名。

例如对于下面的Fortran函数:

DOUBLEPRECISIONFUNCTIONADD(A,B)

!

DEC$ATTRIBUTESDLLEXPORT:

:

ADD

DOUBLEPRECISIONA,B

ADD=A+B

END

对应的C#声明为:

[DllImport("MathDll")]

privatestaticexterndoubleADD(doubleA,doubleB);

使用ALIAS修改后的定义如下:

DoublePrecisionFunctionADD(A,B)

!

DEC$ATTRIBUTESDLLEXPORT:

:

ADD

!

DEC$ATTRIBUTESALIAS:

'Add':

:

Add

DoublePrecisionA,B

Add=A+B

End

对应的C#声明为:

[DllImport("MathDll")]

privatestaticexterndoubleAdd(doubleA,doubleB);

而在C#中提供的解决方案是:

通过使用Dlllmport的EntryPoint属性指定导出的Fortran函数名。

例如:

DoublePrecisionFunctionADD(A,B)

!

DEC$ATTRIBUTESDLLEXPORT:

:

ADD

DOUBLEPRECISIONA,B

ADD=A+B

END

对应的C#声明为:

[DllImport("MathDll",EntryPoint="ADD")]

privatestaticexterndoublePlus(doubleA,doubleB);

此外,还可以使用.NETFramework提供的dumpbin.exe工具查看DLL导出的函数名称。

  A.在开始菜单中打开MicrosoftVisualStudio2010/VisualStudioTools/VisualStudio2010命令提示。

   B.在命令提示窗体中将路径指向编译生成.dll文件的路径,然后输入以下命令:

    dumpbin/exportsFileName.dll

即可查看当前目录下FileName.dIl中导出的所有函数信息。

2.堆栈管理一致

堆栈管理约定包括:

在调用过程中子例程接受参数的数目和顺序,调用完成后由哪一方来清理堆栈等。

C#语言在windows平台上的调用模式默认为StdCall模式,既由被调用方清理堆栈。

而Fortran语言则默认由调用方清除。

因此必须统一调用双方的堆栈清除方式才能保证2种语言间的正常函数调用。

这一约定在Fortran语言或C#语言中均可以采取措施进行统一。

在Fortran语言中可以通过编译指令“!

DEC$”后的可选项“C”或“STDCALL”参数来实现:

A.

!

DEC$ATTRIBUTESSTDCALL:

:

Object

该语句语句中的STDCALL模式指定由被调用方清除堆栈(其中“Object”为变量名或函数名)。

B.

!

DEC$ATTRIBUTESC:

:

Object

该语句中的C模式声明由主调函数清除堆栈(但在传递数组和字符串参数时不能用此方法指定)。

如果在C#语言内做改动,则需要在DllImport属性中设置CallingConvention字段的值为Cdecl(表示由调用方清理堆栈)或StdCall(表示由被调用方清理堆栈)。

[DllImport("FileName.dll",CallingConvention=CallingConvention.StdCall)]

[DllImport("FileName.dll",CallingConvention=CallingConvention.Cdecl)]

只有当Fortran程序和C#程序的堆栈管理一致时,才能保证正常的调用。

3.参数类型保持一致

 在Fortran中常用的数据参数类型有:

REAL:

表示浮点数据类型,即小数,等价于C#的float,

INTEGER:

表示整数类型,相当于C#的int数据类型

DOUBLE PRECISION:

表示双精度数据类型,相当于C#的double数据类型。

 在C#调用FortranDLL是必须保证参数的一致性,例如在Fortran中变量定义的是REAL类型,而我们传入的是Double,那么就会出现计算错误。

三、编写C#代码调用FortranDLL

 

C#调用的Fortran的过程很简单,只需要注意上述说的几个问题即可。

 

这里我们先新建一个控制台应用程序:

 

 

然后将我们编译的Fortran项目所生成的DLL拷贝到控制台应用程序的Debug文件夹下。

接着我们添加一个类:

FortranMethod.cs

该类用来调用FortranDLL。

代码如下:

usingSystem;

usingSystem.Text;

usingSystem.Runtime.InteropServices;

namespaceMixedProgram

{

publicstaticclassFortranMethod

{

[DllImport("TestDll.dll",CallingConvention=CallingConvention.Cdecl)]

publicstaticexterndoubleAdd(doublea,doubleb);

[DllImport("TestDll.dll",CallingConvention=CallingConvention.Cdecl)]

publicstaticexterndoubleSortandfindmax(double[]array,intlength);

}

}

关于C#调用注意的事项在上面已说明,在此不再讨论。

然后在Main函数中测试我们的FortranDLL。

示例代码如下:

usingSystem;

usingSystem.Collections.Generic;

usingSystem.Text;

namespaceMixedProgram

{

classProgram

{

staticvoidMain(string[]args)

{

Console.WriteLine("请输入两个数相加:

");

doublenum1=Convert.ToDouble(Console.ReadLine());

doublenum2=Convert.ToDouble(Console.ReadLine());

Console.WriteLine("输入的两个数是:

"+num1+","+num2);

doublesum=FortranMethod.Add(num1,num2);

Console.WriteLine("求和结果是:

"+sum);

double[]Array={1,5,2,4,3,7,6};

Console.WriteLine("初始数组:

");

for(inti=0;i

Console.Write(Array[i]+"");

doubleb=FortranMethod.Sortandfindmax(Array,Array.Length);

Console.WriteLine("\n"+"排序后:

");

for(inti=0;i

Console.Write(Array[i]+"");

Console.WriteLine("\n"+"最大值为:

");

Console.WriteLine(b);

Console.ReadKey();

}

}

}

到此为止,所以的工作已经完成,下面看一下结果:

到此为止,C#与Fortran编程的小示例就已经完成了。

 

 

总结:

 

本文主要演示了如何使用C#调用Fortran的DLL来实现相关的计算工作。

并主要讲了C#调用时应该注意的事项。

在工程计算中如果对于精度要求较高,计算较复杂时,我们便可以考虑通过C#与Fortran的混合编程来达到所需的要求。

本文是基于本地调用FortranDLL,下一篇将讲解基于Web调用FortranDLL.

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 高等教育 > 农学

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1