admin 管理员组

文章数量: 887016


2024年3月22日发(作者:初中三角函数公式大全图)

22

卷第

4

期洛阳大学学报

Vol.22No.4

                    

2007

12

JOURNALOFLUOYANGUNIVERSITYDec.2007

C

C++

Fortran

混合编程研究

魏 威

,

魏 冲

(

郑州铁路职业技术学院

,

河南郑州

450052

)

摘 要

:

不同计算机编程语言都有其特有的优势和局限性

,

将多种语言混合起来进

行编程

,

不但可以充分发挥各自的优势

,

而且可以弥补各自功能的不足

,

这样既能充分

利用现有程序资源

,

又能加快应用程序的开发

.

主要阐述了

C

C++

Fortran

3

种语

言在不同平台下混合编程应注意的问题

,

以及在混合编程中经常遇到的

2

个问题

.

关键词

:

混合编程

;C;C++;Fortran

中图分类号

:TP311

 文献标识码

:A

 文章编号

:1007-113X

(

2007

)

04-0094-05

Fortran

语言是所有编程语言中惟一能将复数定义为一种标准数据类型的语言

,

其优势在于数值计

,

但是

Fortran

语言在可视化程序设计方面却是非常欠缺的

,

目前还没有一家厂商推出具有

RAD

特性

Fortran

编译集成开发环境

.

当用

Fortran

实现了某一大型科学计算以后

,

却难以将这种计算转变为数

据输入简易、结果显示方便的

Windows

可视化应用程序

,

而采用

C

C++

进行编程却比较容易实现这些

功能

.

因此

,

在许多情况下

,

我们应该使用

C

C++

Fortran

等进行混合编程

.

在混合语言编程中

,

要的问题是函数调用和数据结构的存储

.

1

 

Windows

平台的混合编程

Fortran

语言没有大小写之分

,

Windows

平台下的混合语言编程过程中大小写问题十分突出

.

虑到编译器的差异

,

可以用以下方式进行跨平台编程的函数声明

.C

C++

编译器使用

MicrosoftVisual

C++6.0

编译集成开发环境

,Fortran

编译器使用

DigitalVisualFortran6.0

编译集成开发环境

.

假设一个

C

语言函数为

voidcFunction

()

,

那么只需要在它的头文件里面进行如下定义即可

.

  

#ifdef_cplusplus

  

extern

C

void{

  

#endif

  

externvoid_stdcallCFunction

()

;

  

#definecFunctionCFUNCTION

  

#ifdef_cplusplus

  

}

  

#endif

这样就可实现上述函数在

Fortran

C++

程序中的直接调用

.

假设一个

Fortran

函数为

SUBROUTINEFFUNCTION

()

,

那么在

C++

头文件里可进行如下定义

.

  

#ifdef_cplusplus

  

extern

C

void{

  

#endif

  

externvoid_stdcallffunction

()

;

  

#defineffunctionFFUNCTION

  

#ifdef_cplusplus

3

收稿日期

:2007-11-01

作者简介

:

魏 威

(

1960-

)

,

,

汉族

,

河南省郑州市人

,

工程师

,

研究方向

:

计算机技术

.

© 1994-2009 China Academic Journal Electronic Publishing House. All rights reserved.

4

期             魏 威等

:C

C++

Fortran

混合编程研究      

95

  

}

  

#endif

这样

,

就可以在

C++

的程序里面直接调用上述函数

.

由于

C

编译器里面没有定义

cplusplus

这个环

境变量

,

因此在

C

文件里面也可以直接使用这个头文件

.

如果是一个

C++

函数

voidcPlusplusFunction

()

,

C

函数一样可定义如下

.

  

#ifdef_cplusplus

  

extern

C

void{

  

#endif

  

externvoid_stdcallcPlusplusFunction

()

;

  

#definecPlusplusFunctionCPLUSPLUSFUNCTION

  

#ifdef_cplusplus

  

}

  

#endif

经过上面的定义后

,

所有的函数便可实现在

3

种语言间自由调用

.

在用

3

三种语言进行混合编程过程中要注意函数的参数、字符串的传递问题

.

对含有字符串的函

,

如函数

voidcCharFunction

(

char

3

msg

)

,

需要定义如下

.

  

voidcCharFunction

(

char

3

msg,intlen

)

经过上面的定义之后

,

Fortran

中只需调用

cCharFunction

(

msg

)

即可

.

由于

Fortran

程序没有明显的

字符串结束标志

,

如果是

2

个字符串连在一起

,C

程序里就只能得到

1

个字符串

.

所以

,

最好在

C

的程

序里对这个由

Fortran

程序得到的字符串进行处理

,

因为从

len

变量可以得到字符串长度

,

截取

msg

的前

len

个字符作为这个字符串的应有长度

.

而在

Fortran

程序里面

,

如函数

SUBROUTINEFCHARFUNCTION

(

fchar

)

,

经过相应声明

,

进行下面的定义即可

.

  

#definefCharFunction

(

fchar

)

,FCHARFUNCTION

(

fchar,strlen

(

fchar

))

这样

,

C

C++

程序里即可直接调用

.

3

种语言的混合编程里还有一个需要注意的问题就是指针问题

.Fortran

里面所有的变量都相当于

C

C++

里面的指针

,

所以

,

C

C++

程序里函数的参数应一律声明为指针形式

(

除字符串参数后面

的长度外

)

.

在混合编程过程中

,

数据方面存在的差异也必须引起足够的重视

,

这体现在数组和结构

2

个方面

.

Fortran

语言里

,

数组和

C

C++

里的数组有些不同

,

这表现在行列顺序和数组起始值

.Fortran

语言不同于

C

C++

的行优先

,

而使用列优先的方式

.

假设有一个数组

a,m

n

,

采用行优先时的

数据存放格式如下

.

  

a

11

,a

12

,

,a

1

n

,a

21

,a

22

,

,a

2

n

,

,a

m

1

,a

m

2

,

,a

mn

而采用列优先的数据存放格式如下

.

  

a

11

,a

21

,

,a

m

1

,a

12

,a

22

,

,a

m

2

,

,a

1

n

,a

2

n

,

,a

mn

行优先顺序推广到多维数组

,

规定为先排最右的下标

;

列优先顺序推广到多维数组

,

规定为先排最

左的下标

.

这样

,

在混合语言编程里调用数据时必须注意行列优先的差别

,

进行准确地调用

.

数组的另一个差别是起始下标的不同

.Fortran

默认的数组下标是以

1

开始的

,

C

C++

默认的数

组下标却是从

0

开始的

,

所以在调用时要注意加

1

或者减

1,

以保证调用到正确的数据

.

Fortran

语言里的结构经过声明后就被分配了空间

,

C

C++

里面也要声明它

,

采用下面的方式

.

Fortran

结构声明格式如下

.

  

COMMON/COLOR7/C_RED,C_GREEN,C_BLUE

  

COMMON/NDDAT/NID

(

NASIZE

)

,XN

(

3,NASIZE

)

C

C++

结构声明格式如下

.

  

#ifdef_cplusplus

  

extern"C"{

© 1994-2009 China Academic Journal Electronic Publishing House. All rights reserved.

96

  

#endif

洛阳大学学报                    

2007

  

#definecolor7COLOR7

  

#definenddatNDDAT

  

externstruct{floatc_red;floatc_green;floatc_blue;}color7;

  

externstruct{intnid[NASIZE];floatxn[NASIZE][3];}nddat;

  

#ifdef_cplusplus

  

}

  

#endif

2

 

Linux

平台的混合编程

Linux

平台的混合语言编程和

Windows

平台的混合语言编程基本没有什么区别

,

主要是在

define

的不同

.

考虑到编译器的差异

,

在函数声明上可以用下面的方式进行跨平台编程的函数声明

.C

C++

编译器使用

GNUgcc,Fortran

编译器使用

pgiFortran.

假设一个

C

函数为

voidcFunction

()

,

那么只需要在它的头文件里面进行如下定义即可

.

  

#ifdef_cplusplus

  

extern

C

void{

  

#endif

  

externvoidCFunction

()

;

  

#definecFunctioncfunction_

  

#ifdef_cplusplus

  

}

  

#endif

这样

,

Fortran

或者

C++

的程序里面就可以直接进行调用了

.

需要注意的是

,

函数名应该不多于

31

个字符

.

同样

,

对于

C++

Fortran

里的函数

,

函数名在声明的时候也应改成小写加下划线即可

.

对于数组来说

,

具体变化和

Windows

平台的处理方式是一致的

,

都是行列优先顺序不同的

.

而对于

字符串来说

,

则不需要额外的注意

,gcc

编译器会处理好这个问题

,

也就是说并不需要额外的改变

.

对于数据结构的定义

,

也要改成小写加下划线的方式

.

其中

,Fortran

的数据结构定义方式如下

.

  

COMMON/COLOR7/C_RED,C_GREEN,C_BLUE

  

COMMON/NDDAT/NID

(

NASIZE

)

,XN

(

3,NASIZE

)

C

C++

的数据结构定义方式如下

.

  

#ifdef_cplusplus

  

extern"C"{

  

#endif

  

#definecolor7color7_

  

#definenddatnddat_

  

externstruct{floatc_red;floatc_green;floatc_blue;}color7;

  

externstruct{intnid[NASIZE];floatxn[NASIZE][3];}nddat;

  

#ifdef_cplusplus

  

}

  

#endif

3

 其他平台的混合编程

对于

Solaris

平台

,

基本上和

Linux

平台完全一致

,

但是考虑到

Solaris

大多运行在

SparcCPU

,

是采用

bigendian

,

Windows

Linux

运行在

Intel

AMD

X86

平台上

,

采用的是

littleendian,

一点需要特别注意

,

在读写数据文件时应该给予足够的重视

.

其他的

Unix

平台

,

HPUnix

ULTRIX

IRIS

,

一般都只有

define

上的微小差别

,

在字符串处理、结构及数组方面基本与

Linux

相同

.

对它们

© 1994-2009 China Academic Journal Electronic Publishing House. All rights reserved.

4

期             魏 威等

:C

C++

Fortran

混合编程研究      

97

来说

,

考虑更多的应该是中央处理器不同带来的差别

.

4

 混合编程中的字符串处理

混合编程中经常会出现需要传递字符串的情况

,

而字符串的传递是一个较为麻烦的问题

.

Fortran

,

字符串是没有结束符的

,

但是有长度的概念

,

也就是说

,

编译器会给每一个字符串一个长度以控制

字符串的长度

,

但是这个长度参数在不同的平台下其位置也是不同的

(

有的直接跟在字符串后面

,

有的

则跟在函数参数的最后面

)

,

对于常见的平台

,

Windows

Linux

Solaris

HPUnix

IRIS,

可以用如下方

法定义

.

C

函数为例

,

定义如下

.

  

voidmessag

(

char

3

msg1,int

3

where1,char

3

msg2,int

3

where2

)

  

{

  

printf

(

“……

%sshouldbe%d,while%sshouldbe%dn

,msg1,

3

where1,msg2,where2

)

;

  

}

如果要在

Fortran

里调用的话

,

需要以下定义

.

  

#ifdefinedULTRIX||SPARC||IRIS||LINUX||WIN32

  

#ifdefinedULTRIX||SPARC||IRIS||LINUX

  

externvoid_stdcallmessag

(

char

3

,int

3

,char

3

,int

3

,int,int

)

  

#definemessag

(

s1,i1,s2,i2

)

messag_

(

s1,i1,s2,i2,strlen

(

s1

)

,strlen

(

s2

))

  

#else/

3

WIN32Platform

3

/

  

externvoid_stdcallmessag

(

char

3

,int,int

3

,char

3

,int,int

3

)

  

#definemessag

(

s1,i1,s2,i2

)

MESSAGE

(

s1,strlen

(

s1

)

,i1,s2,strlen

(

s2

)

,i2

)

  

#endif

  

#else/

3

OtherPlatform

3

/

  

externvoid_stdcallmessag

(

char

3

,int

3

,char

3

,int

3

,int,int

)

  

#definemessag

(

s1,i1,s2,i2

)

messag

(

s1,i1,s2,i2,strlen

(

s1

)

,strlen

(

s2

))

  

#endif

如果要用在

C++

,

需要如下定义

.

  

#ifdef_cplusplus

  

extern

C

{

  

#endif

  

/

3

yourexterncode

3

/

  

#ifdef_cplusplus

  

}

  

#endif

Fortran

里便可以直接调用如下

.

  

CALLMESSAG

(

char1,i1,char2,i2

)

同样

,

Fortran

里写的字符串处理函数使用以上的

define

extern

,

也可以在

C

里直接调用

.

5

 混合编程中的文件读写处理

文件读写也是混合编程中一个非常重要的问题

,

通常的问题发生于不同平台下的混合编程或者不同

Fortran

编译器间的编译

.

Fortran

,

文件的写入是由

write

语句完成的

,

而每一个

write

语句可一次性写入多个数据构成一

个数据块

,

而每一个无格式数据块都由下面

3

部分组成

:

(

1

)

数据块的开始标志

,

记录所有数据所占的

字节数

;

(

2

)

组成该数据块的各数据内容

.

整型数和浮点数均占

4

个字节

,

低字节在前

,

高字节在后

.

数据间不空格

;

(

3

)

每个数据块的结束标志

,

也为该数据块的字节数

,

而不是以回车换行符作为结束标

.

各记录之间也没有分隔符

.

另外

,

由于编程语言的差异

,

不同的编译器的存储格式也存在差异

,

VisualFortran

DigitalFortran

在存储数据块中还存在着差别

.

在一个

write

语句中

,VisualFortran

存储数据块的开始标志与结束标志是

© 1994-2009 China Academic Journal Electronic Publishing House. All rights reserved.

98

洛阳大学学报                    

2007

用一个字节表示

,

而在

DigitalFortran

是用一个整形数

,

4

个字节来表示

.

也就是说

,VisualFortran

个数据块最多可以存储

128

个字节

,

如果一个

write

语句要求写入的数据量大于

128

字节时

,

则按循环形

式存入

.

所以

,DigitalFortran

在读取时就应该把它转化为相应的

DigitalFortran

存储形式

.

6

 结束语

混合编程的优势在于它允许调用用另一种语言编写的现有程序代码、使用在特定语言环境下难以实

现的算法和获得处理速度方面的优势

.

在混合编程中的关键问题是协调

2

种或多种语言间所的调用约

定、命名约定及参数传递方式

,

并使它们在数据结构、数据类型上保持一致

.

参考文献

:

[1]

孙 鑫

,

余安萍

.VisualC++

深入详解

[M].

北京

:

电子工业出版社

,2006.

[2]

埃克尔

.C++

编程思想

[M].

北京

:

机械工业出版社

,2002.

[3]

任 哲

.MFCWindows

应用程序设计

[M].

北京

:

清华大学出版社

,2004.

[4]

周振红

.Fortran90/95

高级程序设计

[M].

郑州

:

黄河水利出版社

,2006.

[5]

周振红

.IntelVisualFortran

应用程序开发

[M].

郑州

:

黄河水利出版社

,2006.

[6]

浩强工作组

.Fortran

经典程序设计

[M].

大连

:

大连理工大学出版社

,2004.

[7]

霍 顿

.VisualC++2005

入门经典

[M].

北京

:

清华大学出版社

,2007.

[8]StanleyB,ialC++[M].

武汉

:

华中科技大学出版社

,2001.

StudyonMixed

2

languageCompilingUsingC,C++andFortran

WEIWei,WEIChong

(

ZhengzhouRailwayVocationalandTechnicalCollege,Zhengzhou450052,China

)

ABSTRACT:Therearedifferentpeculiaradvantageandlimitationineachkindofprogramminglanguage.

Themixingprogrammingcanmakethebestofmeritsofdifferentlanguagesandavoidthedeficienciesofthem.

ThispapermainlydiscussthequestionofmixingprogrammingusingtheC,C++andFortran.

KEYWORDS:mixingprogramming;C;C++;Fortran

(

责任编辑

:

王 晓

)

© 1994-2009 China Academic Journal Electronic Publishing House. All rights reserved.


本文标签: 编程 混合 字符串 数据 语言