js55金沙娱乐:C#与Fortran混合编制程序之本地调用Fortran动态链接库

世家好,DLL是先前VC++编写的,主要用以各个总括,三十一位。供其余非.NET程序调用的。今后有须要开拓二个VB.NET的次第,刚巧能够动用DLL中的一些考虑逻辑,所以想一直运用。有局地不知道的地点:1,.Net编写翻译的时候蓬蓬勃勃班筛选AnyCPU。这样的话在陆拾一人主机上相应就是遵照六十三人运转的,当时,调用的叁十一位DLL会有怎么着难题啊?2,DLL是不是应该被编写翻译成六16个人的更加好?依旧说实在和DLL是32人60人未有其余关联?因为是新春以内,又是竞标阶段,所以来不比试了。即便有兄弟有相像的经验,麻烦共享。谢谢!

前言

  1. 实现Matlab函数

大器晚成、基本思路

利用Fortran,编写动态链接库(DLLState of Qatar,在DLL中提供总结的函数接口,然后在C#中调用该DLL中计算部分的函数,实现总计进程。

此处须要注意的是,由于大家选用的是Fortran编译器,生成的DLL归于第三方非托管DLL,因而不能够直接在前后相继中加多DLL的援引。具体的做法将要连续部分表达。

 

Best Regards

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

明亮思路之后便早先专门的学业的Coding。首先新建三个空的Fortran Dynamic-link Library项目。

js55金沙娱乐 1

在AMD(奇骏卡塔尔国 Visual Fortran点击Library,选中右图的Dynamic-link Library.然后点击OK.此时的类型如下所示:

js55金沙娱乐 2

点击Sources File文件夹,选取新建项。

js55金沙娱乐 3

加上贰个新的Fortran文件

js55金沙娱乐 4

下一场便最早Fortran代码的编写专门的学问。这里大家根本实现四个主意:

一个办法是求七个数相加之和,并回到结果。

另三个是输入一个数组,对这几个数组实行排序,并找寻最大值,最后回到排序后的结果,并回到最大值。

这里大家独家演示的是Fortran传出几个数和一个数组有什么不一致。

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

上面给出的上述大家要兑现的效能的求实Fortran代码:

DOUBLE PRECISION FUNCTION ADD(A,B)
!DEC$ ATTRIBUTES DLLEXPORT::ADD
!DEC$ ATTRIBUTES STDCALL,ALIAS:'Add'::ADD
    DOUBLE PRECISION:: A,B
    ADD=A+B
END

FUNCTION SORTANDFINDMAX(ARRAY,LENGTH)
!DEC$ ATTRIBUTES DLLEXPORT::SORTANDFINDMAX
!DEC$ ATTRIBUTES STDCALL,ALIAS:'Sortandfindmax'::SORTANDFINDMAX
DOUBLE PRECISION ::ARRAY(LENGTH)
INTEGER::I,J
DOUBLE PRECISION::SORTANDFINDMAX,TEMP
SORTANDFINDMAX=ARRAY(1)
DO I=1,LENGTH-1
    DO J=I+1,LENGTH
        IF(ARRAY(I).GT.ARRAY(J)) THEN
            TEMP=ARRAY(I)
            ARRAY(I)=ARRAY(J)
            ARRAY(J)=TEMP
            SORTANDFINDMAX=ARRAY(J)
            END IF
    END DO
    END DO
END

地点大家评释了两个Fortran函数,一个是总结多少个数相加,二个是选择排序并寻觅最大值。

今后大家点击Visual Studio的Build Solution.开首编写翻译成DLL。

关于代码段解释:

!DEC$ ATTRIBUTES DLLEXPORT::ADD

!DEC$ ATTRIBUTES STDCALL,ALIAS:'Add'::ADD

这两句代码相当的重大。上面通过多个相通来归纳的说一下之上代码段的意思和C#调用要求注意的问题。

1.函数名肖似:

在Fortran编写翻译器中暗中同意的导出函数名全副是大写情势。而在C#中调用Fortran Dll时必须指定函数名相仿。在Fortran方面化解的章程是:使用ALIAS(别名State of Qatar属性钦定导出函数名。

比方说对于下面的Fortran函数:

DOUBLE PRECISION FUNCTION ADD(A, B)

!DEC$ ATTRIBUTES DLLEXPORT:: ADD

DOUBLE PRECISION A,B  

ADD =A+B

END

对应的C#声明为:

[DllImport("MathDll")]

private static extern double ADD (double A, double B);

行使ALIAS更正后的概念如下:

Double Precision Function ADD (A, B)

!DEC$ ATTRIBUTES DLLEXPORT:: ADD

!DEC$ ATTRIBUTES ALIAS:'Add' :: Add

Double Precision A,B  

Add =A+B

End

对应的C#声明为:

[DllImport("MathDll")]

private static extern double Add (double A, double B);

而在C#中提供的解决方案是:通过应用Dlllmport的EntryPoint属性钦点导出的Fortran函数名。

例如:

Double Precision Function ADD(A, B)

!DEC$ ATTRIBUTES DLLEXPORT:: ADD

DOUBLE PRECISION A,B  

ADD =A+B

END

对应的C#声明为:

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

private static extern double Plus(double A, double B);

除此以外,还足以行使 .NET Framework提供的dumpbin.exe工具查看DLL导出的函数名称。

    A. 在开端菜单中开垦Microsoft Visual Studio 2008/Visual Studio Tools/ Visual Studio 二〇一〇 命令提醒。

js55金沙娱乐 5

     B. 在指令提示窗体司令员路线指向编写翻译生成.dll文件的路子,然后输入以下命令:

        dumpbin /exports FileName.dll

就能够查看当前目录下FileName.dIl中程导弹出的装有函数新闻。

js55金沙娱乐 6

2. 仓房产和土地资金财产管理理均等

货仓处理约定富含:在调用进度中子例程选择参数的多少和顺序,调用实现后由哪一方来清理仓库等。C#语言在windows平台上的调用方式默以为StdCall形式,既由被调用方清理仓库。而Fortran语言则暗中认可由调用方扑灭。因而必需联合调用两个的商旅消逝方式才具保险2种语言间的例行函数调用。那生机勃勃约定在Fortran语言或C#语言中均可以采纳措施实行联合。

在Fortran语言中得以经过编写翻译指令“!DEC$”后的可选项“C”或“STDCALL”参数来兑现:

A.

!DEC$ ATTRIBUTES STDCALL ::Object

该语句语句中的STDCALL形式钦赐由被调用方息灭货仓(个中“Object”为变量名或函数名)。

B.

!DEC$ ATTRIBUTES C :: 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#调用Fortran DLL是必需保障参数的大器晚成致性,比如在Fortran中变量定义的是REAL类型,而笔者辈传入的是Double,那么就能够产出计量错误。

  1. 调用DLL时,程序报错"MathWorks.MATLAB.NET.Utility.MWMCTiggo.mclCreateComponentData,错误描述是:传递给系统调用的数量区域太小"

Fortran是一门古老的言语,它是世界上最初出现的微处理机高等程序设计语言,广泛应用张永琛确和工程测算领域。FORTRAN语言以其特有的法力在数值、科学和工程测算领域发挥器重大成效。不过Fortran程序自己不合乎开辟独立的应用程序,举例大家古板的桌面应用或许Web应用。因而这里大家便想将C#与Fortran结合,C#依赖Fortran能够兑现精度更高,总计更加快的主次,而Fortran通过C#,便也能够达成可视化设计。

 1 using System.Data;
 2 using System.Drawing;
 3 using System.Linq;
 4 using System.Text;
 5 using System.Windows.Forms;
 6 using MathWorks.MATLAB.NET.Utility;
 7 using MathWorks.MATLAB.NET.Arrays;
 8 using test;
 9 
10 namespace testMatlab
11 {
12     public partial class Form1 : Form
13     {
14         public Form1()
15         {
16             InitializeComponent();
17 
18             label6.Text = "";
19         }
20         
21         private void button1_Click(object sender, EventArgs e)
22         {
23             //Get input number from UI
24             int iTextBox1 = int.Parse(textBox1.Text.ToString());
25             int iTextBox2 = int.Parse(textBox2.Text.ToString());
26                         
27             MWArray result = null;
28             MWNumericArray a = new MWNumericArray(iTextBox1);
29             MWNumericArray b = new MWNumericArray(iTextBox2);
30 
31             
32             //call function testAdd, provided by Matlab
33             Test t = new Test();
34             result = t.testAdd((MWArray)a, (MWArray)b);
35 
36 
37             int y = ((MWNumericArray)result).ToScalarInteger();
38             
39             //show result in UI
40 
41             textBox3.Text = y + "";
42             label6.Text = "Get the result by Matlab DLL, Answer: " + y;
43         }
44     }
45 }

C#演化到几最近,已然是一门一定周全的言语,他根据C语言风格,演变于C++。并依据强大的.NET底层框架。C#能够用来飞速营造桌面及Web应用。不过在大家的莫过于工作中,就算C#曾经特别完美,但要么不可能达成大家全部的做事。在无数工程测算中,C#语言的总结速度,精度,甚至推行效用相对来说都达不到品种的渴求。因而大家便构思是不是有后生可畏种格局将大家的工程估测计算部分和大家的系列分别,将计算部分用另黄金年代种施行越来越快,精度更加高的言语来编排,然后在C#中调用,最终成功大家的干活。答案是鲜明的。

     js55金沙娱乐 7

 

  2. 编译testAdd.m,得到DLL文件,以便由C#引用

三、编写C#代码调用Fortran DLL

 

C#调用的Fortran的进度十分轻巧,只要求注意上述说的多少个难点就可以。

 

此地大家先新建叁个调整台应用程序:

 

js55金沙娱乐 8

 

下一场将大家编写翻译的Fortran项目所生成的DLL拷贝到调控台应用程序的Debug文件夹下。

js55金沙娱乐 9

随之大家抬高中二年级个类:FortranMethod.cs

此类用来调用Fortran DLL。

代码如下:

using System;
using System.Text;
using System.Runtime.InteropServices;

namespace MixedProgram
{
   public static class FortranMethod
    {
       [DllImport("TestDll.dll",CallingConvention = CallingConvention.Cdecl)]
       public static extern double Add(double a, double b);

       [DllImport("TestDll.dll", CallingConvention = CallingConvention.Cdecl)]
       public static extern double Sortandfindmax(double[] array, int length);
    }
}

关于C#调用注意的事项在上头已表明,在这里不再斟酌。

下一场在Main函数中测量试验大家的Fortran DLL。

示范代码如下:

using System;
using System.Collections.Generic;
using System.Text;

namespace MixedProgram
{
    class Program
    {
        static void Main(string[] args)
        {
            Console.WriteLine("请输入两个数相加:");
            double num1=Convert.ToDouble(Console.ReadLine());

            double num2 = Convert.ToDouble(Console.ReadLine());
            Console.WriteLine("输入的两个数是:" + num1 + " ," + num2);
            double sum = FortranMethod.Add(num1,num2);
            Console.WriteLine("求和结果是:"+sum);

            double[] Array = { 1,5,2,4,3,7,6};
            Console.WriteLine("初始数组:");
            for (int i = 0; i < Array.Length; i++)
                Console.Write(Array[i]+" ");

            double b=FortranMethod.Sortandfindmax(Array, Array.Length);
            Console.WriteLine("\n"+"排序后:");

            for (int i = 0; i < Array.Length; i++)
                Console.Write(Array[i]+" ");

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

            Console.ReadKey();
        }
    }
}

到此截至,所以的行事早已成功,上边看一下结果:

js55金沙娱乐 10

到此结束,C#与Fortran编制程序的小示例就已经完结了。

 

 

总结:

 

本文首要演示了什么样使用C#调用Fortran的DLL来得以完结相关的乘除专门的工作。并注重讲了C#调用时应有专心的事项。在工程测算中大器晚成旦对于精度须要较高,总结较复杂时,大家便能够虚构通过C#与Fortran的搅和编制程序来达成所需的供给。本文是依靠本地调用Fortran DLL,下生龙活虎篇将助教基于Web调用Fortran DLL.

 

 关于C#与Fortran混合编程还可出席那篇小说:

 

 

(版权全体,转载请标记出处卡塔尔(قطر‎

 

二.  完成步骤

      这里本人建了名字为"test"的工程,选用project类型时,应选取.NET Component,因为此处笔者急需其当作C#的援用。同期注意这里的工程名,就是你编写翻译出DLL的称号,同不时间C#次第调用时,"Test"即为封装Matlab函数的类名。他将您的工程名,首字母大写用为高端语言中的类名。

     Matlab R2009a(Version 7.8.0.347)

    A. 打开Matlab R2009a,新建testAdd.m文件

    D. 点击"Build"编写翻译文件(如下图所示)

 

      首先将testAdd.m增加到test工程下Test文件夹中(右击Test,选取Add File)(介意:这里并非选用中文路线,详见下方六.测量试验进度中Bug记录)。

    

  C#程序:

   js55金沙娱乐 11

 

  由此,可实现C#对Matlab算法的调用。当然这里只是本身付出供给时,设计的三个小例子。由于Matlab总括,输入与结果供给大量的矩阵,那C#与在这之中间的数据沟通也是经过MWArray实行,只要依据接口标准,都得以兑现。这里不再研商,英特网资料也超级多。

Kevin Song