关闭

ILE下的各种语言(C/C++, CL, RPG, COBOL)的混合编程实例及原理简介

标签: cobol语言编程moduleobjectservice
1560人阅读 评论(1) 收藏 举报

 本文转载:http://www-128.ibm.com/developerworks/cn/aix/library/au-crosslanguage/

    在IBM System i平台上,ILE是Integrated Language Environment 的缩写,意思为集成语言环境。ILE是被设计用来提升IBM System i上程序开发的一系列工具和相关的系统支持。在System i平台ILE环境下,C/C++、CL、RPG、COBOL语言编写的程序可以编译成Module Object。Module Object可以直接链接成可执行的Program Object,也可以链接成不能直接执行的Service Program Object,这些Service Program Object可以和其他的Program Object链接后即变成可直接执行的Object。Object的编译链接过程如下图所示:

ILE 示意图

 

    通常情况下,程序只能调用用本语言编写的Procedure,而不调用其他语言编写的Procedure。本文将要讲述的混合编程打破了这一常规,在ILE环境下,通过各种语言编写的模块之间互相调用彼此的Procedure来实现各种语言的混合编程。例如CL(Control Language)编写的模块中可以调用C/C++、RPG、COBOL编写的Procedure,C语言程序中也可以调用CL、RPG、COBOL编写的Procedure。

 

 

ILE中的几个重要概念

 

    在讲述混合编程之前,首先简单介绍ILE中的几个重要概念。

 

    Procedure:

    一段高级语言编写的source,它可以详细地完成某项任务,然后返回给调用者。对C语言而言,Procedure就是一个函数;对CL而言,Procedure其实就是一个CL程序的source。

   

    Module:

    Module是由ILE编译器编译出来的,不可以执行的Object。Module包含有一个或多个Procedure和一些数据信息,以及在这个Module中一些Procedure和数据导出导入信息。当然,有些Module还包含调试信息,这取决于你如何编译程序。Module的结构如下图所示:

Module结构 (示意图来自ILE Concepts

 

    在Module Object M1中,导出了两个Procedure(Draw_Line和Draw_Arc)和一个数据项(rtn_code);同时,M1也导入一个Procedure(Draw_Plot)。这个Module Object包含有一个PEP(程序入口函数,在C中是main函数)和一个UEP(Procedure Draw_Arc)。另外,Module Object M1还包含一些调试信息。  

 

 

    Service Program :

    Service Program 是ILE链接器把一个或多个Module链接在一起而生成的Object。Service Program不可以直接在System i上执行。从某种角度来看,System i平台上的Service Program类似Windows平台上的DLL(Dynamic Link Library)。Service Program 中导出的Procedure和数据可以被Program 或者其他的Service Program调用。Service Program的public interface中定义了其他ILE Object可以访问的Procedure和数据信息,我们可以通过binder language来定义Service Program的public interface。

       

    Service Program 一般包含有Module相关的数据信息,Procedure和数据导出导入信息和调试信息。Service Program 至少有一个UEP,没有PEP。Service Program 的结构如下图所示:

Service Program 结构 (示意图来自ILE Concepts

 

     SPGMEXAMP Service Program中,包含有4个Module(M1、M2、M3和M4)。SPGMEXAMP的public interface有Procedure P3、P4和数据项D。P3是在Module M3中定义的,P4是在Module M4中定义的。另外SPGMEXAMP调用了其他ILE Object提供的print Procedure。

 

 

    Program :

    Program 是ILE链接器把一个或者多个Module Object绑定链接而成的可以执行的Object。Program 是由一个或多个Module链接而成,有时还需要链接Service Program。Program 有且只有一个程序入口PEP,但可以有多个UEP。PEP是在程序链接CRTPGM时,由参数ENTMOD来指定哪个Module的PEP为程序的PEP。Program 的结构如下图所示:

 

   

Program 结构 (示意图来自ILE Concepts)

 

 

ILE下混合编程示例

 

    首先分别用CL, C/C++, RPG, COBOL五种语言各编写一个Module。Module提供一个Procedure,实现简单的打印功能,打印出hello world!信息。所有模块的source存在/qsys.lib/ile_test.lib/mod_source.file中,可以在后面sample中找到离子的source。

                                                                               

       1。CL(Control Language)程序

       CL编写的Procedure是程序把Hello World!消息发送到用户RAOYQ,所以事先需要创建用户RAOYQ。CL程序源码如下:

 

    使用编译命令 “CRTCLMOD MODULE(ILE_TEST/CLMODULE) SRCFILE(ILE_TEST/MOD_SOURCE)  SRCMBR(CL_MODULE)“ ,在ILE_TEST库中生成CLMODULE Object。使用“DSPMOD MODULE(ILE_TEST/CLMODULE) DETAIL(*PROCLIST)”命令可以查看到Module导出的Procedure情况,CL Procedure导出的Procedure名称就是Module的名称。注意:其它ILE object调用这个Procedure, 必须使用CLMODULE这个名称。CLMODULE的结构如下图所示:

CLMODULE Module结构示意图

 

    Module Object CLMODULE中只导出一个Procedure(CLMODULE);同时,Module导入一系列系统提供的Procedure(CEEGOTO Qcl_CHKBI、Qcl_LkLDA等)。这个Module Object包含有一个PEP和一个UEP(CLMODULE)。

 

    2。C程序

    C语言编写的Procedure是一个C函数,打印"Hello World! Print by C module/n"信息到控制台。程序的源码如下所示:

 

    通过CRTCMOD MODULE(ILE_TEST/CMODULE) SRCFILE(ILE_TEST/MOD_SOURCE) SRCMBR(C_MODULE)可以把源码编译成Module Object。 C Procedure导出的Procedure名称就是函数的名称,其它ILE Object调用这个Procedure,调用函数名就可以了。如果C Procedure会被其他语言的ILE Object调用,如CL、COBOL、RGP,Procedure的名称必须大写,这些语言不能识别小写Procedure名。

 

   

    3。C++程序

    C++语言编写的是一个HelloOperation类,类中定义有一个Procedure PrintHello。在这个Procedure中,"Hello World! Print by C++ module/n"被输出到Console。HelloOperation类定义在/QSYS.LIB/ILE_TEST.LIB/HPP.FILE/CPP_HEADER.MBR中,HelloOperation实现在/QSYS.LIB/ILE_TEST.LIB/MOD_SOURCE.FILE/CPP_MODULE.MBR中,source如下所示:

 

 

 

       用 CRTCPPMOD MODULE(ILE_TEST/CPPMODULE) SRCFILE(ILE_TEST/MOD_SOURCE)  SRCMBR(CPP_MODULE)命令可以把上面的C++ Procedure编译成Module。由于C++语言是面向对象的语言,不同于C、CL等面向过程的语言,所以调用C++编写的Procedure不能直接调用HelloOperation类的函数成员PrintHello,需要先创建一个对象,故在其他语言(C除外)中调用C++写的比较困难。如果必须使用,可以用extern “C"来声明类Procedure名以避免C++中的命名mangle问题

 

    4。RPG程序

    RPG程序编写的例子是把“Hello World!”和“PRINT BY RPG”消息打印出来。程序的source如下所示:

      

       用 CRTRPGMOD MODULE(ILE_TEST/RPGMODULE) SRCFILE(ILE_TEST/MOD_SOURCE) SRCMBR(RPG_MODULE)命令可以把上面的RPG source 编译成Module,执行DSPMOD MODULE(ILE_TEST/RPGMODULE) DETAIL(*PROCLIST)命令可以查看到Module导出的Procedure情况。RPG  Module导出的Procedure名称如下图所示。RPG  Procedure导出的Procedure名称一般就是Module的名称,其它ILE Object可以直接调用这个Procedure。

   

    5。COBOL程序

    COBOL程序编写的例子是把“Hello World! print by cobol!“ 消息打印出来。程序的source如下所示:

 

       CRTCBLMOD MODULE(ILE_TEST/CBLMODULE) SRCFILE(ILE_TEST/MOD_SOURCE)  SRCMBR(CBL_MODULE)命令可以把上面的COBOL source 编译成Module,可以用DSPMOD MODULE(ILE_TEST/CBL_MODULE) DETAIL(*PROCLIST)查看到Module导出的Procedure情况,CBL Procedure导出的Procedure名称是在COBOL程序中定义的名称,其它ILE Object调用这个Procedure,可以通过调用该函数名来实现。注意:如果你在COBOL Module中试用STOP RUN。将导致COBOL MODULE停止运行,也会使外部的调用者停止运行。本文的实例就出现这个问题,可以删除该行,调用后面例子中的make文件SAMPLE_MK重新编译。

   

   

    ILE环境下,实现各种语言的混合编程的基础是:不管使用的编程语言是那一种,编译出来的Module都是一致的。对于System i系统而言,CLMODULE、CMODULE、CPPMODULE、RPGMODULE和CBLMODULE具有Module Object相同的各种属性,不同的地方只有Module导出的函数和数据不一样。可以通过DSPMOD命令可以查看这些Module相同的和不同的各种属性。

 

 

    上面由不同语言编写Procedure的Module可以通过CRTSRVPGM 链接成Service Program Object。链接器把这些Module Object的数据和Procedure信息都考入Service Program Object中,数据和Procedure导出由binder language来定义。默认情况下Service Program Object会导出各个Module所导出的所有数据和Procedure。binder language语言的格式如下:

 

   

    调用者可以直接调用Module Object中提供的数据和Procedure,也可以调用Service Program导出的数据和Procedure。如果外部调用者调用Service Program导出的数据和Procedure时,调用者运行时才调用导出的数据和Procedure,既在调用者运行时才链接上Service Program。如果外部调用者调用Module Object提供的数据和Procedure,在调用者编译成Program时,就必须把提供数据和Procedure包含进调用者的Program Object。另外,Service Program Object可以由binder language来定义到处接口,而Module Object导出则不能定义。本文使用的示例是调用Service Program Object提供的数据和Procedure。

   

 

   

    正是由于各种语言编写的Module的一致性,所以调用者调用其他语言编写Module提供的数据和Procedure时,就象调用本语言编写Module提供的数据和Procedure一样。C语言中调用CL提供的Procedure,直接调用Module或者Service Program提供的Procedure,就如同调用其他C函数一样,编译链接时,把这个提供Procedure的Object加上就可以。

 

    下面是一个C调用者的程序源码,存放在/qsys.lib/ile_test.lib/caller.file/c.mbr中。

 

    在例子中,我们分别用五种语言编写了提供一个Procedure服务的Module。C语言编写Module是CMODULE,提供的Procedure是CPRINTHELLO。C++语言编写Module是CPPMODULE,提供的是一个HelloOperation类。CL语言编写Module是CLMODULE,提供的Procedure是CLMODULE 。RPG语言编写Module是RPGMODULE,提供的Procedure是RPGMODULE 。COBOL语言编写Module是CBLMODULE,提供的Procedure是CBLPRINTHELLO。下表横向项就列出了五种语言编写MODULE所提供的Procedure。由于其他语言调用C++编写的Procedure比较麻烦,我没有在表中列出具体的实现,所以用灰色表示这一列。

 

    表竖项列出了五种语言编写的调用者。C调用者调用CL提供的CLMODULE Procedure,可以直接调用CLMODULE( );调用COBOL提供的CBLMODULE Procedure,可以直接调用CBLMODULE( );调用RPG提供的RPGMODULE Procedure,可以直接调用RPGMODULE( )。其他语言的调用,与C一样,如下表所示:

 

 

C

C++

CL

COBOL

RPG

Caller

CPRINTHELLO Procedure

PrintHello__14HelloOperationFv Procedure

CLMODULE Procedure

CBLPRINTHELLO Procedure

RPGMODULE Procedure

C

CPRINTHELLO( )

 

CLMODULE ()

CBLPRINTHELLO()

RPGMODULE()

C++

CPRINTHELLO( )

 

CLMODULE ()

CBLPRINTHELLO()

RPGMODULE()

CL

CALLPRC PRC(PRINTHELLO)

 

CALLPRC PRC(CLMODULE )

CALLPRC

PRC(CBLPRINTHELLO)

CALLPRC

PRC(RPGMODULE)

COBOL

CALL LINKAGE TYPE IS PROCEDURE 'CPRINTHELLO'.

 

CALL LINKAGE TYPE IS PROCEDURE 'CLMODULE '.

CALL LINKAGE TYPE IS PROCEDURE 'CBLPRINTHELLO'.

CALL LINKAGE TYPE IS PROCEDURE 'RPGMODULE'.

RPG

CALLB(D)'CPRINTHELLO'

 

CALLB(D) 'CLMODULE '

CALLB(D)

'CBLPRINTHELLO'

CALLB(D)

'RPGMODULE'

 

 

 

混合编程Demo使用

 

    把ile_sample.savf文件通过FTP传送到i5/OS系统上,restore这个文件。sample中有一个make文件SAMPLE_MK,使用CRTBNDCL PGM(ILE_TEST/SAMPLE_MK) SRCFILE(ILE_TEST/SAMPLE_MK) SRCMBR(MK)命令编译这个make文件,然后调用这个make文件就可以编译所有的sample例子了。C_CALLER.PGM就是上面的例子,里面还有CL_CALLER.PGM,CBL_CALLER.PGM和RPG_CALLER.PGM。

   

 

    

 

 

参考文献

    1。《ILE Concept》 http://publib.boulder.ibm.com/infocenter/iseries/v5r3/topic/books/sc415606.pdf

0
0

查看评论
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
    个人资料
    • 访问:4845次
    • 积分:81
    • 等级:
    • 排名:千里之外
    • 原创:4篇
    • 转载:0篇
    • 译文:0篇
    • 评论:1条
    文章分类
    文章存档