fortran与c语言接口参数传递混合编程.docx
《fortran与c语言接口参数传递混合编程.docx》由会员分享,可在线阅读,更多相关《fortran与c语言接口参数传递混合编程.docx(30页珍藏版)》请在三一办公上搜索。
1、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处理器也是如
2、此,只是x86系统未定义REAL*16和 COMPLEX*32数据类型,这些数据类型只能用于SPARCo11.1兼容性问题大多数C-Fortran接口必须在以下这些方面全部保持一致: 函数和子例程的定义及调用 数据类型的兼容性 参数传递(按引用或按值) 参数的顺序 过程名(大写、小写或带有结尾下划线(_) 向链接程序传递正确的库引用某些C-Fortran接口还必须符合: 数组索引及顺序 文件描述符和stdio 文件权限11.1.1函数还是子例程?函数一词在C和Fortran中有不同的含义。根据具体情况做出选择很重要:在C中,所有的子程序都是函数;但void函数不会返回值。在Fortran中,函
3、数会传递一个返回值,但子例程一般不传递返回值。当Fortran例程调用C函数时: 如果被调用的C函数返回一个值,则将其作为函数从Fortran中调用。 如果被调用的C函数不返回值,则将其作为子例程调用。当C函数调用Fortran子程序时: 如果被调用的Fortran子程序是一个函数,则将其作为一个返回兼容数据类型 的函数从C中调用。 如果被调用的Fortran子程序是一个子例程,则将其作为一个返回int (与Fortran INTEGER*4兼容)或void值的函数从C中调用。如果Fortran子 例程使用交替返回,则会返回一个值,这种情况下它是RETURN语句中的表达 式的值。如果RETUR
4、N语句中没有出现表达式,但在SUBROUTINE语句中声 明了交替返回,则会返回零。11.1.2数据类型的兼容性表112总结了 Fortran 95 (与C比较)数据类型的数据大小和缺省对齐。该表假设 未应用影响对齐或提升缺省数据大小的编译选项。请注意以下事项: C数据类型int、long int和long在32位环境下是等同的(4字节)。 但是,在64位环境下long和指针为8字节。这称为LP64数据模型。 在64位SPARC环境下,当用任意m64选项进行编译时, REAL*16和COMPLEX*32与16字节边界对齐。 标有4/8的对齐表示缺省情况下与8字节边界对齐,但在COMMON块中与
5、 4字节边界对齐。COMMON中的最大缺省对齐为4字节。当用m64选项进 行编译时,4/8/16表示与16字节边界对齐。 REAL(KIND=16)、REAL*16、COMPLEX(KIND=16)、COMPLEX*32 只 能用于SPARC平台。 数组和结构的元素及字段必须兼容。 不能按值传递数组、字符串或结构。 可以在调用点使用VAL(arg),按值将参数从Fortran 95例程传递到C例 程。假如Fortran例程具有一个显式接口块,该接口块用VALUE属性声明了伪 参数,则可以按值将参数从C传递到Fortran 95。 数值序列类型的组件的对齐方式与通用块的对齐方式相同,也会受到al
6、igncommon选项的影响。数值序列类型是这样一种序列类型:其中所 有组件的类型为缺省整数、缺省实数、双精度实数、缺省复数或缺省逻辑,而不 是指针。 在大多数情况下,非数值序列类型的数据类型组件以自然对齐的方式对齐,但 QUAD变量除外。对于四精度变量,32位SPARC平台和64位SPARC平 台之间的对齐方式不同。 在所有平台上,用BIND(C)属性定义的VAX结构和数据类型的组件始终与 C结构具有相同的对齐方式。表11 -数据大小与对齐一(以字节表示)按引用传递(f95和cc)1Fortran 95数据类型C数据类型大小对齐1 BYTE xchar x111CHARACTER xunsi
7、gned char x ;111CHARACTER (LEN=n) xunsigned char xn;n11COMPLEX xstruct float r,i; x;841COMPLEX (KIND=4) xCOMPLEX (KIND=8) xCOMPLEX (KIND=16)x (SPARC)struct float r,i; x;struct double dr,di; x;struct long double, dr,di; x;8163244/84/8/161 DOUBLE COMPLEX xstruct double dr, di; x;164/81 DOUBLE PRECISIO
8、N xdouble x ;841 REAL xfloat x ;441REAL (KIND=4) xREAL (KIND=8) xREAL (KIND=16)x (SPARC)float x ;double x ;long double x ;481644/84/8/161INTEGER xint x ;441INTEGER (KIND=1) xsigned char x ;141Fortran 95数据类型C数据类型亲对齐1INTEGER (KIND=2) xshort x ;24INTEGER (KIND=4) xint x ;44INTEGER (KIND=8) xlong long i
9、nt x;841 LOGICAL xint x ;441LOGICAL (KIND=1) xsigned char x ;14LOGICAL (KIND=2) xshort x ;24LOGICAL (KIND=4) xint x ;44LOGICAL (KIND=8) xlong long int x;8411.1.3大小写敏感性C和Fortran在区分大小写方面采取截然相反的处理方法: C区分大小写一大小写很重要。 Fortran在缺省情况下忽略大小写。f95缺省通过将子程序名转换成小写来忽略大小写。除了字符串常量以外,它会将所有 大写字母都转换成小写字母。对于大/小写问题,有两种常用解决
10、方案: 在C子程序中,使C函数名全为小写。 用-U选项编译Fortran程序,该选项会通知编译器保留函麴子程序名称的现 有大/小写区别。只能采用这两种解决方案中的一种,不能同时采用。本章大多数示例的C函数名均采用小写字母,并且没有使用f95-U编译器选项。11.1.4例程名中的下划线Fortran编译器通常会在入口点定义和调用中都出现的子程序名末尾追加一个下划线 (_)。该惯例不同于具有相同的用户指定名称的C过程或外部变量。几乎所有Fortran 库过程名都有两个前导下划线,以减少与用户指定的子例程名的冲突。对于下划线问题,有三种常用解决方案: 在C函数中,通过在函数名末尾追加下划线来更改该名
11、称。 使用BIND(C)属性声明来指明外部函数是C语言函数。 使用f95ext_names选项编译对无下划线的外部名称的引用。只能使用上述解决方案中的一种。本章的示例都可以使用BIND(C)属性声明来避免下划线。BIND(C)声明可从 Fortran调用的C外部函数,以及可从C中作为参数调用的Fortran例程。Fortran 编译器在处理外部名称时通常不追加下划线。BIND(C)必须出现在每个包含这样的引 用的子程序中。惯常用法是:在此处,用户不仅指定XYZ是外部C函数,而且还指定Fortran调用程序ABC应该 可以从C函数调用。如果使用BIND(C),C函数不需要在函数名末尾追加下划线。
12、11.1.5按引用或值传递参数通常,Fortran例程按引用传递参数。在调用中,如果非标准函数%VAL()中包含一个 参数,则调用例程会按值传递该参数。Fortran 95按值传递参数的标准方法是通过VALUE属性和INTERFACE块。请参 见11.4按值传递数据参数。C通常按值传递参数。如果在参数前加上表示和”的符号(&),C会使用指针按引用传 递参数。C总是按引用传递数组和字符串。11.1.6参数顺除字符串参数之外,Fortran和C均以相同的顺序传递参数。但对于每个字符型参数, Fortran例程都会传递一个附加参数,用以指定串长度。这些参数在C中是long int数量,按值进行传递。
13、参数顺序为:与每个参数相应的地址(数据或函数)与每个字符参数对应的long int (字符串长度的完整列表位于其他参数的完 整列表之后)示例:Fortran代码片段:等价的C代码片段:char s7;int b3;CHARACTER*? S INTEGER B(3)CALL SAM( S, B(2)sam ( s, &b1, 7L );11.1.7数组索引和顺序Fortran与C的数组索引和顺序不同。11.1.7.1数组索引C数组总是从0开始,而Fortran数组在缺省情况下是从1开始。有两种常用的索 引处理方法。 如上述示例所示,可以使用Fortran缺省设置。此时,Fortran元素B(2
14、)等 同于C元素b1。 可以指定Fortran数组B以B(0)开始,如下所示:INTEGER B(0:2)这样,Fortran元素B(1)就等同于C元素b111.1.7.2数组顺序Fortran数组按列主顺序存储:A(3,2)A(1,1)A(2,1)A(3,1)A(1,2)A(2,2)A(3,2)C数组按行主顺序存储:A32A00 A01 A10 A11 A20 A21 这对于一维数组不存在任何问题。但对于多维数组,应注意下标在所有引用和声明中是 如何出现和使用的一可能需要做些调整。例如,在C中进行部分矩阵操作,而后在Fortran中完成余下部分,这样做可能会产 生混淆。最好是将整个数组传递给
15、另一语言中的例程,然后在该例程中执行所有矩阵操 作,以避免在C和Fortran中各执行部分操作的情况。11.1.8文件描述符和stdioFortran I/O通道采用的是单元号。底层SunOS操作系统不处理单元号,而是处理文 件描述符。Fortran运行时系统会不断变换,所以大多数Fortran程序没必要识别文件 描述符。许多C程序都使用一组称为标准I/O (即stdio)的子例程。有许多Fortran I/O函 数也使用标准I/O,而后者又使用操作系统I/O调用。下表列出了这些I/O系统的某 些特性。表11 2 Fortran与C之间的I/O比较1Fortran 单元标准I/O文件指针文件描
16、述符I文件 打 开为读写打开为读打开、为写打开、为 读写打开,或者为追加打开;请参见 open (2)为读打开、为写打开 或同时为读写打 开1属性己格式化或未格 式化始终未格式化,但可用格 式解释例程进行读或写始终未格式化1访问直接或顺序直接访问(如果物理文件 的表示是直接访问),但 总是可以按顺序读取直接访问(如果物理 文件的表示是直接 访问),但总是可以 按顺序读取1结构记录字节流字节流1形式0-2147483647 间 的任意非负整 数指向用户地址空间中结构 的指针0-1023间的整数11.1.9库与使用f95命令链接要链接正确的Fortran和C库,请使用f95命令调用链接程序。示例1
17、:用编译器进行链接:demo% cc -c someCroutine.cdemo% f95 theF95routine.f someCroutine.o r = 32.;w - i = .007;z - r = 66.67;z - i = 94.1;在64位 环境下,在寄存器中返回COMPLEX值。11.3.3字符串由于没有标准接口,因此不推荐在C与Fortran例程间传递字符串。不过,请注意以 下方面: 所有C字符串均按引用传递。 Fortran调用会为参数列表中具有字符类型的每个参数传递一个附加参数。此额 外参数给出串长度,它等同于按值传递的C长整数。(这要依具体实现而定。) 额外的串长度
18、参数出现在调用中的显式参数之后。下例展示了具有字符串参数的Fortran调用及其等同的C调用:1Fortran 调用:等价的C调用:I1INTEGER B(3)int b3;. CALL CSTRNG( S, B(2). . cstrng_( s, &b1, 7L ); 如果在被调用例程中不需要串长度,则可以忽略额外的参数。但要注意,Fortran不会 自动以C期望的显式空字符来终结字符串。该终结符必须由调用程序添加。字符数组调用与单个字符变量调用看起来一样。会传递数组的起始地址,所使用的长度 是数组中单个元素的长度。11.3.4 一维数组在C中数组下标以0开始。表11 6传递一维数组1For
19、tran 调用 CC 调用 Fortran1integer i, Sum integer a(9) external FixVec call FixVec ( a, Sum ) extern void vecref_(int, int * ); int i, sum;int v9 = vecref_( v, &sum ); void fixvec_ ( int v9, int *sum ) int i;*sum = 0;subroutine VecRef( v, total)integer i, total, v(9)total = 011.3.5二维数组C与Fortran间的行列转换。表11
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- fortran 语言 接口 参数 传递 混合 编程
链接地址:https://www.31ppt.com/p-4884620.html