第11章 Fortran和C的混合语言编程-授课版
- 格式:ppt
- 大小:811.50 KB
- 文档页数:24
VC++调用Fortran子程序VC++友好的界面制作和Visual Fortran强大的计算和数据处理功能,两者结合可开发行程界面友好、操作直观方便、功能强大的应用程序。
如何进行VC++调用VisualFortran子程序模块,就成了需要解决的问题。
1、VC++调用FORTRAN子程序的方式(1)同一工程包含VC++和Fortran语言文件对同一版本集成后的编译器可以根据不同的扩展名选择编译方式,生成目标代码文件.OBJ,然后按照指定的调用方式进行链接,生成可执行文件.EXE。
(2)VC++工程文件引用Fortran语言生成的.OBJ或.LIB文件对不同版本的编译器安装集成后,VS不会自动根据文件扩展名选择编译方式,这时需用不同的工程文件。
首先对Visual Fortran 建一工程文件,生成.OBJ文件或.LIB文件,然后在VC++工程中按照指定的调用方式进行调用,编译链接,生成可执行文件.EXE。
(3)VC++工程文件调用Fortran语言生成的.DLL将已有的Fortran程序生成dll模块,有利于移植和修改,可提高效率,这样即使原dll模块中的算法做过修改,只要保证函数或子例行程序名字和入口参数不变,主调用过程无须进行重新修改或者编译。
2、VC++中的声明在C++语言中调用Fortran的函数或模块,必须在C++语言的函数名前面冠以_s td call或_cdecl关键字申明调用方式,以便编译器按照约定方式进行正确的参数传递,包括参数传递顺序、参数传递方式、堆栈处理和命名修饰等问题。
C++语言调用Fortran模块的声明:extern “C” {void _stdcall SUBROUTINE(形式参数1,float TC[],float PC,……);float _stdcall FUNCTION(形式参数1,float TC[],float PC,……); } 或extern “C” {void _cdecl SUBROUTINE(形式参数1,float TC[],float *PC,……);float _cdecl FUNCTION(形式参数1,float TC[],float *PC,……); } 其中TC为数组变量。
1.VS2008+INTELfortran.Fortran为主程序,调用c++函数2.VS2008的设置(1)在已有的fortran工程的解决方案中添加新的c++工程:解决方案可以有好多工程;但是每个工程只能是单独计算机语言的工程,即fortran用fortran建立工程,c++用c++建立工程。
设置解决方案中,各个工程之间的依赖关系。
(2)混合编程的几种方法:c++源文件编译为目标文件与fortran链接合成;c++源文件编译为库文件,然后fortran链接的时候将该库加入。
2.设置runtimelibrary:Multithreaded;而d e bug模式中,r untime library竟然是:M u ltithreaded DLL然能链接通过。
换M u ltithread 和M u ltithreaded DLL 竟的候有而且时,出错交3. 设置项目依赖关系:项目-》项目依赖项3)链接选项(以c++为静态链接库为例)如图库,下接(1)构建或改变c++工程为静态链(2)在主较多:设置比要程(f o rtran工程),需工设置l inker里面附加库(a d ditionary library)的目录和库名称linker-》additionay Library directory设置为:F:\LBM_MOVING_INTER2_FLEXIBLE\LBM_MOVING_INTER2_FLEXIBLE\Release(c++编译为静态库,库所在的目录)\称设置名:库的加附F:\LBM_MOVING_INTER2_FLEXIBLE\LBM_MOVING_INTER2_FLEXIBL E\Release\beamcpp.liblinker-》input-》a ddtionary dependencies:F:\LBM_MOVI NG_INTER2_FLEXIBLE\LBM_MOVING_INTER2_FLEXIBLE\Release\beamcpp.lib4)源程序c++函数的f ortran接口fortran为主程序,即program main{implicit noneint::i,jdoubleprecision,dimension(20)::p.....call GETBEAMDV(i,j,p...)}c++程序中#include <assert.h>#include <iostream>#include <fstream>#include <string>class myclass{...};extern "C"{void GETBEAMDV(int* ,int*,double*);}void GETBEAMDV(int* MM,int*kk,double* Pld){.....return;};几点注意:(1)ifort 编译后(fortran源程序),其函数名为大写名称前方加底横线:如“_GETBEAMDV”(2)VISUAL C++编译后(c++源程序),其函数名也为大写名称前方加底横线:如“_GETBEAMDV”因此,只需相同名称就可以了,比codeblock简单些!!!另外,为了使程序在codeblocks 和 vs2008一致,可在vs2008中进行设置,包括c++和fortran工程中添加编译和链接选项分别为:简单在vs2008的fortran工程中添加编译选项:/names:lowercase增只要加“_”的话这样call getbeamdv(i,j,p...) !!getbeamdv_((i,j,p...))用于intel fortran 编译(编译选项添加/names:lowercase,具体参见vs2008+ifort)。
C/C++/Fortran混合编程浅谈(一)直接链接方式现今流行很多编程语言,在编译型语言中,C/C++/Fortran语言应用非常广泛,C以其效率高效底层操作为著称,C++以其很好的面向对象类框架泛型编程为特点,Fortran则以现世存有大量的计算程序而占有重要的位置,在编程中,集合他们三者的长处是个很好的做法。
混合编程有很多方法,以下介绍一下基本方法。
对于各个编译器,如果编译中间的二进制文件.o或.obj的结构相同,则可以直接链接混合编程。
遵循约定:C/C++默认传值,Fortran传址。
一、相同编译器家族以gcc家族为例,类似的还有Intel C Compiler和Intel Fortran Compiler等。
1、C和Fortran(1)C调用Fortranmain.csub.f90sub.f90(F2003方式)链接方法gcc –o main.o –c main.cgfortran –o sub.o –c sub.f90gcc –o main.exe main.o sub.o或者直接gcc –o main.exe main.c sub.f90 输出(2)Fortran调用Cmain.f90sub.c链接方式gcc –o sub.o sub.cgfortran –o main.o main.f90 gfortran –o main.exe main.o sub.o 或是直接gfortran –o main.exe main.f90 sub.c 输出visual C++与FORTRAN混合编程(2010-04-22 14:15:25)转载标签:分类:科研visualcfortran混合编程原文:/143577510.html本文示例说明用C++编写的主程序调用采用FORTRAN语言编写的子程序的方法。
方法一:直接在Microsoft Developer Studio创建包含c语言和FORTRAN语言的工程。
fortran与c语言接口参数传递混合编程Sun Studio 12:Fortran 编程指南Previous: 第10 章并行化第11 章C-Fortran 接口本章论述Fortran 与C 的互操作性方面的问题,内容仅适用于Sun Studio Fortran 95 和C 编译器的特定情况。
11.9 Fortran 2003 与C 的互操作性简要说明了Fortran 2003 标准第15 部分中提到的C 绑定功能。
(此标准可以从国际Fortran 标准Web 站点获得)。
Fortran 95 编译器实现了标准中所述的这些功能。
如不特别注明,32 位x86 处理器视为与32 位SPARC 处理器等同。
对于64 位x86 处理器和64 位SPARC 处理器也是如此,只是x86 系统未定义REAL*16 和COMPLEX*32 数据类型,这些数据类型只能用于SPARC。
11.1 兼容性问题大多数 C-Fortran 接口必须在以下这些方面全部保持一致:函数和子例程的定义及调用数据类型的兼容性参数传递(按引用或按值)参数的顺序过程名(大写、小写或带有结尾下划线(_))向链接程序传递正确的库引用某些C-Fortran 接口还必须符合:数组索引及顺序文件描述符和stdio文件权限11.1.1 函数还是子例程?函数一词在C 和Fortran 中有不同的含义。
根据具体情况做出选择很重要:?在C 中,所有的子程序都是函数;但void函数不会返回值。
在Fortran 中,函数会传递一个返回值,但子例程一般不传递返回值。
当Fortran 例程调用C 函数时:如果被调用的C 函数返回一个值,则将其作为函数从Fortran 中调用。
如果被调用的C 函数不返回值,则将其作为子例程调用。
当C 函数调用Fortran 子程序时:如果被调用的Fortran 子程序是一个函数,则将其作为一个返回兼容数据类型的函数从 C 中调用。
C/C++/FORTRAN 混合编程混合编程在软件编程中是经常遇到的问题,尤其是C/C++/FORTRAN的混合编程,本文主要说明以上三种语言混合编程中经常遇到的问题,同时,也说明了不同平台下混合编程应注意的问题。
混合语言编程要注意的问题主要体现在:函数调用和数据结构的存储。
1 Windows平台函数:由于Fortran编程语言没有大小写之分,Windows平台下的混合语言编程要注意的主要是大小写的问题。
考虑到编译器的差异,可以用下面的方式进行跨平台编程的函数声明。
( C/C++编译器使用Microsoft Visual C++ 6.0, Fortran编译器使用 Digital Visual Fortran 6.0)。
假设一个C的函数为 void cFunction(); 那么,只需要在它的头文件里面进行如下定义即可:#ifdef __cplusplusextern “C” void {#endifextern void __stdcall CFunction();#define cFunction CFUNCTION#ifdef __cplusplus}#endif这样,在Fortran或者C++的程序里面就可以直接调用了。
假设是一个Fortran函数SUBROUTINE FFUNCTION(); 那么,在C++头文件里进行如下的定义就可以了:#ifdef __cplusplusextern “C” void {#endifextern void __stdcall ffunction();#define ffunction FFUNCTION#ifdef __cplusplus}#endif这样,就可以在C++的程序里面直接调用。
由于C编译器里面,没有定义__cplusplus这个环境变量,因此,C文件里面,也可以直接使用这个头文件。
如果是一个C++函数,如: void cPlusplusFunction();和c函数一样,进行下面的定义即可:#ifdef __cplusplusextern “C” void {#endifextern void __stdcall cPlusplusFunction ();#define cPlusplusFunction CPLUSPLUSFUNCTION#ifdef __cplusplus}经过上面的定义后,所有的函数便可以在三种语言中自由调用。
C#与Fortran混合编程-本地调用Fortran动态链接库Fortran是一门古老的语言,它是世界上最早出现的计算机高级程序设计语言,广泛应用于科学和工程计算领域。
FORTRAN语言以其特有的功能在数值、科学和工程计算领域发挥着重要作用。
然而Fortran程序本身不适合开发独立的应用程序,例如我们传统的桌面应用或者Web应用。
因此这里我们便想将C#与Fortran 结合,C#借助Fortran可以实现精度更高,计算更快的程序,而Fortran通过C#,便也能够达到可视化设计。
一、基本思路运用Fortran,编写动态链接库(DLL),在DLL中提供计算的函数接口,然后在C#中调用该DLL中计算部分的函数,实现计算过程。
这里需要注意的是,由于我们使用的是Fortran编译器,生成的DLL属于第三方非托管DLL,因此无法直接在程序中添加DLL的引用。
具体的做法将在后续部分说明。
二、编写Fortran程序,生成动态链接库文件知道思路之后便开始正式的Coding。
首先新建一个空的Fortran Dynamic-link Library项目。
在Intel(R) Visual Fortran点击Library,选中右图的Dynamic-link Library.然后点击OK.这时的项目如下所示:点击Sources File文件夹,选择新建项。
添加一个新的Fortran文件然后便开始Fortran代码的编写工作。
这里我们主要实现两个方法:一个方法是求两个数相加之和,并返回结果。
另一个是输入一个数组,对这个数组进行排序,并找出最大值,最后返回排序后的结果,并返回最大值。
这里我们分别演示的是Fortran传出一个数和一个数组有何不同。
关于Fortran的基本语法不是本文的讨论范畴,请读者自行查阅资料。
下面给出的上述我们要实现的功能的具体Fortran代码:DOUBLE PRECISION FUNCTION ADD(A,B)!DEC$ ATTRIBUTES DLLEXPORT::ADD!DEC$ ATTRIBUTES STDCALL,ALIAS:'Add'::ADDDOUBLE PRECISION:: A,BADD=A+BENDFUNCTION SORTANDFINDMAX(ARRAY,LENGTH)!DEC$ ATTRIBUTES DLLEXPORT::SORTANDFINDMAX!DEC$ ATTRIBUTES STDCALL,ALIAS:'Sortandfindmax'::SORTANDFINDMAX DOUBLE PRECISION ::ARRAY(LENGTH)INTEGER::I,JDOUBLE PRECISION::SORTANDFINDMAX,TEMPSORTANDFINDMAX=ARRAY(1)DO I=1,LENGTH-1DO J=I+1,LENGTHIF(ARRAY(I).GT.ARRAY(J)) THENTEMP=ARRAY(I)ARRAY(I)=ARRAY(J)ARRAY(J)=TEMPSORTANDFINDMAX=ARRAY(J)END IFEND DOEND DOEND上面我们声明了两个Fortran函数,一个是计算两个数相加,一个是选择排序并找出最大值。