您好,欢迎访问三七文档
当前位置:首页 > 电子/通信 > 综合/其它 > Fortran混合编程
FORTRAN混合编程概述~~~~~~~~~~主要内容混合语言编程概述参数传递协议命名约定堆栈管理定义Fortran中过程的原型在VIF(XE2011)环境下混合编程混合语言编程概述概念:由两种以上语言写成的源代码形成的程序的过程。混合语言编程综合了不同语言之间的优点,使得编程更加快捷。Fortran适合科学计算,VisualC++更适合于图形界面编程;两者结合能加快编程开发速度。这里主要介绍Fortran和C/C++的混合编程问题!!混合语言编程概述1、混合编程的难点是解决不同语言之间的通信问题2、而程序之间的通信是通过例程之间的相互调用实现的。3、不同语言间的语法规范不同,要正确通信,必须,必须建立统一的约定,即调用约定。这里的例程是不同语言的函数、过程、子例程的总称调用约定参数传递命名约定堆栈考虑参数传递协议参数传递包括以下四个方面,参数传递顺序:Fortran和C/C++实参和虚参的对应顺序都是从左到右。参数传递方式:值传递或者地址传递。参数数目是否可变:是否识别可选参数参数数据类型:整型,浮点,字符……√参数传递协议(一)——参数传递方式参数传递方式由Attributes属性指定,两种方式:方式一、c,stdcall选项:Subroutines1(a,b,c)!DEC$attributesC::s1Real(4)a,b,cEndsubroutineC、stdcall声明过程遵循Windows标准参数传递方式,就是C语言参数传递模式区别是什么呢……参数传递协议——参数传递方式方式二,reference,value选项:Subroutines1(a,b,c)!DEC$attributesvalue::a,bReal(4)a,b,cEndsubroutineReference和value选项能单独指定输入参数的传递方式Reference指定参数为引用传递,这正是Fortran默认的传值方式Value指定参数为值传递,这正可以适应C/C++的传值方式参数传递协议——参数传递方式以上讨论的均是在Fortran源程序中作改动,实际上由于C/C++含有指针这一特殊类型,就不需要再对值传递和引用传递另外作声明了。Subroutines1(a,b,c)!DEC$attributesvalue::a,bReal(4)a,b,cEndsubroutineExtern“C”Void_stacalls1(floata,floatb,float*c);参数传递协议(二)——参数数目C++可以定义参数可选的函数,对于这种情况Fortran如何处理呢?Real(4)functionfunc(x,a,b)!dec$attributesc,varying::func!dec$attributesalias:’_func’::funcReal(4)x,a,bEndfunction由Fortran调用C++程序extern“C”floatfunc(floatx,floata=0,floatb=0){floatf;f=a*x*x+b*x*x;returnf;}主程序:Programa1Write(*,*)func(1.0,3.0)end参数传递协议——参数数目结论:如果Fortran需要调用带有可选参数的C++函数,须在fortran程序中用c,Varying对例程进行声明。!dec$attributesc,varying::例程名选项C的作用,在后面堆栈管理约定时详细介绍。参数传递协议(三)——数据类型FortranC/C++Integer(2)shortInteger(4)Int,longReal(4)floatReal(8)doubleFortran和C/C++对应的数据类型命名约定名称约定包括变量名称、例程名称、模块名称(fortran)等。混合编程真正“混合”的是在不同语言汇编形成的目标文件。对名称的约定也就是对.obj文件中相应名称所作的约定!Fortran对大小写不敏感,但C/C++对大小写确实严格区分的。编译的过程命名约定Fortran中对名称的声明分三种情况:一、缺省不管fortran源文件中名称如何,在.obj文件中名称一律大写。二、指定C、stdcall选项不管fortran源文件中名称如何,在.obj文件中名称一律小写。三、Alias指定别名在.obj文件中名称与Alias规定的名称完全相同。命名约定C/C++对名称说明:不论是缺省还是用cdecl、stdcall声明,名称均保留混合大小写。C++的命名约定和C略有不同,C++生成的obj文件中名称有对外部符号的修饰,一般在声明时加上extern“C”,使其丢掉修饰而与C的命名规则一致。命名约定汇总表语言属性.Obj中名称name的大小写Fortran!DEC$atrributesC_name全部小写Fortran!DEC$AttributesStdcall_name@n全部小写Fortran缺省_name@n全部大写CCdel(缺省)_name大小写混合C_stdcall_name@n大小写混合C++缺省_name@@deroction大小写混合注:name为定义的函数或子例程名称@n代表调用时堆栈地址,n为虚参列表占堆栈的大小注意,Alias服从这些法则实际上,当用Fortran调用C/C++编写的程序(含有混合大小写时),必须用Alias声明别名。因为Attributes属性其他选项无法实现混合大小写的声明。命名约定(示例)Subroutineadd(a,b,c)!DEC$AttributesC::addInteger(4)a,b,cC=a+bEndsubroutineextern“C”voidadd(int*a,int*b,int*c);voidmain(){inta=1,b=2,c=0;add(&a,&b,&c);printf(“c=%d”,c);}Subroutineadd(a,b,c)!DEC$Attributesstdcall,Alias‘_add@12’::add!dec$Attributesreference::a,b,cInteger(4)a,b,cC=a+bEndsubroutineSubroutineadd(a,b,c)!DEC$Attributesstdcall,Alias:‘_add@12’::add!dec$Attributesreference::a,bInteger(4)a,b,cC=a+bEndsubroutine命名约定(示例)Subroutineadd(a,b,c)Integer(4)a,b,cC=a+bEndsubroutineextern“C”_cdeclADD(int*a,int*b,int*c)voidmain(){inta=1,b=2,c=0;ADD(&a,&b,&c);printf(“c=%d”,c);}Subroutineadd(a,b,c)!DEC$Attributesc,Alias:‘_add@12’::AddInteger(4)a,b,cC=a+bEndsubroutineextern“C”_cdeclAdd(int*a,int*b,int*c)voidmain(){inta=1,b=2,c=0;Add(&a,&b,&c);printf(“c=%d”,c);}命名约定(续)Fortran调用C/C++定义的函数:programmainimplicitnonereal(8)::a=2.0,b=3.0,cinterfacefunctionadd2(m,n)!dec$attributesstdcall,alias:'_Add2@16'::add2real(8)m,n,add2endfunctionendinterfaceprint*,add2(a,b)read(*,*)cend#includestdio.hexternCdouble_stdcallAdd2(doublem,doublen){returnm+n;}别名命名约定(续)fortran中模块的名称Fortran模块名称在.obj文件中的形式为_MODULENAME_mp_ENTITY[@stacksize]modulett1implicitnonecontainsfunctionmult(a,b)!dec$attributesc::mult!dec$attributesvalue::a,breal(4)a,b,multmult=a*bendfunctionmultendmoduleexternCvoid_cdecladd(int*a,int*b,int*c);externCfloat_cdeclTT1_mp_mult(floata,floatb);intmain(){inta=1,b=2,c=0;add(&a,&b,&c);printf(c=%d,c);floatct;ct=TT1_mp_mult(a,b);printf(\nct=%f,ct);scanf(%d,&c);}堆栈管理程序之间例程的调用都是通过堆栈实现的,先将例程地址、例程参数压入堆栈,然后再弹出例程参数和例程地址。堆栈满足先进后出的原则。在声明调用约定C的情况下,当执行程序由被调例程返回时,由调用程序负责出栈、清理堆栈的工作;缺省约定和Stdcall约定条件下,由被调用例程控制堆栈。正因为在C约定下,由调用程序控制堆栈,调用程序知道有多少参数被传递,占多少个字节,驻留在堆栈的什么位置等信息,所以在C约定下可以传递可变数量的参数。在C约定之外规定外部例程拥有Varying属性,就能实现例程参数数目可变。realfunctiionff(x,a,b,c)!dec$attributesC,Varying::ffendfunctionextern“C”double(doublex,doublea,doubleb=0.0,doublec=0.0)定义FORTRAN过程原型当要用Fortran调用其他语言的程序时,应该在Fortran源代码中定义例程的原型(接口块)interface例程语句[例程attributes属性][参数Attributes属性]正式参数声明end例程endinterface……Attributes属性和前面的声明方法、作用完全一样示例VIF(XE2011)环境下混合编程VS2010环境下不能同时将多个语言的源程序放在同一个项目中编译,Fortran和C/C++源程序需先编译成目标文件.obj,然后在主程序所在工程中链接形成.exe文件。Fortran调用C++C++调用FortranVIF(XE2011)环境下混合编程fortran调用C/C++函数很容易实现,在Visualstudio环境下,需要将编译器默认的运行库设置debugmultithreaded修改为multithreaded,否则会出现如下的错误:VIF(XE2011)环境下混合编程C/C++调用Fortran例程:仅仅将Fortran生成的.obj文件添加到项目中还不够,另外还需要将Fortran编译器下的一些静态库包含进来。在安装目录下:ComposerXE-2011\compiler\lib\ia32THEENDThankyou例程的等价形式语言有返回值调用无返回值调用Fortran函数(Function)子例程(Subroutine)C/C++有返回值的函数空函数(void)C/C++、FORTRAN参数传递方式的区别C/C++:除数组外的其他所有非指针参数均采用值传递的方式。Fortran:除常量、表达式外所有数值型参数均采用引用传递(地址传递)。C/C++源代码到可执行文件的过程源代码编译预处理编译汇编链接可执行文件处理#define,#ifdef,#include等语句,对源代码的改写和扩充词法、语法分析,将代码翻译成中间代码将翻译的代码翻译成目标机器码目标文件彼此链接形成.exe文件编译
本文标题:Fortran混合编程
链接地址:https://www.777doc.com/doc-4338734 .html