ILE 环境下的各种语言(C/C++, CL, RPG, COBOL)的混合编程实例及

2024-03-27 10:40

本文主要是介绍ILE 环境下的各种语言(C/C++, CL, RPG, COBOL)的混合编程实例及,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

引用:http://www.ibm.com/developerworks/cn/aix/library/au-crosslanguage/index.html

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

在 IBM System i 平台上 ILE 环境下,如何实现 C/C++, CL, RPG, COBOL 的混合编程

级别: 中级

饶 有清, IBM 软件工程师, IBM 中国软件开发中心
王 虎, IBM 软件工程师, IBM 中国软件开发中心

2007 年 9 月 13 日

本文简要介绍了 IBM System i 平台上 ILE 编程原理,以及如何在 ILE 环境下实现 C/C++、COBOL、RPG 和 CL 的混合编程,在文章的结束部分给出了一个简单的 Demo。

ILE(Integrated Language Environment)

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 的编译链接过程如下图所示:


图.1
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 的结构如下图所示:


图.2
Module 结构图 
 

在 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 的结构如下图所示:


图.3
Service Program结构图 
 

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

Program:

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


图.4
Program 结构图 


ILE 下混合编程示例

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

1。CL(Control Language)程序

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


图.5
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调 用这个P rocedure, 必须使用 CLMODULE 这个名称。CLMODULE 的结构如下图所示:


图.6
CLMODULE 结构图 
 

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"信息到控制台。程序的源码如下所示:


图.7
程序源码 
 

通过 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 如下所示:


图.8
cpp 头文件 

图.9
cpp 源码 
 

用 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 如下所示:


图.9
RPG 程序 
 

用 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。


图.10
Procedure名称 
 

 

5。COBOL 程序

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


图.11
COBOL程序 
 

用 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 程序中定义的名称,其它I LE 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 语言的格式如下:


图.12
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。


图.13
示例 
 

正是由于各种语言编写的 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 中。


图.14
C调用者源码 
 

 

在例子中,我们分别用五种语言编写了提供一个 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 一样,如下表所示:


调用各种语言编写的 Procedure 列表

C C++ CL COBOL RPG
Caller
CPRINTHELLO ProcedurePrintHello__14HelloOperationFv ProcedureCLMODULE ProcedureCBLPRINTHELLO ProcedureRPGMODULE 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 传送到系统上,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。


下载

描述 名字 大小 下载方法
本文用到示例的 source
ile_sample.savf11KBHTTP
关于下载方法的信息


 

参考资料

  • ILE Concept

这篇关于ILE 环境下的各种语言(C/C++, CL, RPG, COBOL)的混合编程实例及的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/851834

相关文章

从入门到精通C++11 <chrono> 库特性

《从入门到精通C++11<chrono>库特性》chrono库是C++11中一个非常强大和实用的库,它为时间处理提供了丰富的功能和类型安全的接口,通过本文的介绍,我们了解了chrono库的基本概念... 目录一、引言1.1 为什么需要<chrono>库1.2<chrono>库的基本概念二、时间段(Durat

Go语言中nil判断的注意事项(最新推荐)

《Go语言中nil判断的注意事项(最新推荐)》本文给大家介绍Go语言中nil判断的注意事项,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友参考下吧... 目录1.接口变量的特殊行为2.nil的合法类型3.nil值的实用行为4.自定义类型与nil5.反射判断nil6.函数返回的

C++20管道运算符的实现示例

《C++20管道运算符的实现示例》本文简要介绍C++20管道运算符的使用与实现,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧... 目录标准库的管道运算符使用自己实现类似的管道运算符我们不打算介绍太多,因为它实际属于c++20最为重要的

Visual Studio 2022 编译C++20代码的图文步骤

《VisualStudio2022编译C++20代码的图文步骤》在VisualStudio中启用C++20import功能,需设置语言标准为ISOC++20,开启扫描源查找模块依赖及实验性标... 默认创建Visual Studio桌面控制台项目代码包含C++20的import方法。右键项目的属性:

Go语言数据库编程GORM 的基本使用详解

《Go语言数据库编程GORM的基本使用详解》GORM是Go语言流行的ORM框架,封装database/sql,支持自动迁移、关联、事务等,提供CRUD、条件查询、钩子函数、日志等功能,简化数据库操作... 目录一、安装与初始化1. 安装 GORM 及数据库驱动2. 建立数据库连接二、定义模型结构体三、自动迁

SQLite3 在嵌入式C环境中存储音频/视频文件的最优方案

《SQLite3在嵌入式C环境中存储音频/视频文件的最优方案》本文探讨了SQLite3在嵌入式C环境中存储音视频文件的优化方案,推荐采用文件路径存储结合元数据管理,兼顾效率与资源限制,小文件可使用B... 目录SQLite3 在嵌入式C环境中存储音频/视频文件的专业方案一、存储策略选择1. 直接存储 vs

c++中的set容器介绍及操作大全

《c++中的set容器介绍及操作大全》:本文主要介绍c++中的set容器介绍及操作大全,本文通过实例代码给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友参考下吧... 目录​​一、核心特性​​️ ​​二、基本操作​​​​1. 初始化与赋值​​​​2. 增删查操作​​​​3. 遍历方

java向微信服务号发送消息的完整步骤实例

《java向微信服务号发送消息的完整步骤实例》:本文主要介绍java向微信服务号发送消息的相关资料,包括申请测试号获取appID/appsecret、关注公众号获取openID、配置消息模板及代码... 目录步骤1. 申请测试系统2. 公众号账号信息3. 关注测试号二维码4. 消息模板接口5. Java测试

解析C++11 static_assert及与Boost库的关联从入门到精通

《解析C++11static_assert及与Boost库的关联从入门到精通》static_assert是C++中强大的编译时验证工具,它能够在编译阶段拦截不符合预期的类型或值,增强代码的健壮性,通... 目录一、背景知识:传统断言方法的局限性1.1 assert宏1.2 #error指令1.3 第三方解决

C++11委托构造函数和继承构造函数的实现

《C++11委托构造函数和继承构造函数的实现》C++引入了委托构造函数和继承构造函数这两个重要的特性,本文主要介绍了C++11委托构造函数和继承构造函数的实现,具有一定的参考价值,感兴趣的可以了解一下... 目录引言一、委托构造函数1.1 委托构造函数的定义与作用1.2 委托构造函数的语法1.3 委托构造函