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

相关文章

Python中Tkinter GUI编程详细教程

《Python中TkinterGUI编程详细教程》Tkinter作为Python编程语言中构建GUI的一个重要组件,其教程对于任何希望将Python应用到实际编程中的开发者来说都是宝贵的资源,这篇文... 目录前言1. Tkinter 简介2. 第一个 Tkinter 程序3. 窗口和基础组件3.1 创建窗

利用c++判断水仙花数并输出示例代码

《利用c++判断水仙花数并输出示例代码》水仙花数是指一个三位数,其各位数字的立方和恰好等于该数本身,:本文主要介绍利用c++判断水仙花数并输出的相关资料,文中通过代码介绍的非常详细,需要的朋友可以... 以下是使用C++实现的相同逻辑代码:#include <IOStream>#include <vec

基于C++的UDP网络通信系统设计与实现详解

《基于C++的UDP网络通信系统设计与实现详解》在网络编程领域,UDP作为一种无连接的传输层协议,以其高效、低延迟的特性在实时性要求高的应用场景中占据重要地位,下面我们就来看看如何从零开始构建一个完整... 目录前言一、UDP服务器UdpServer.hpp1.1 基本框架设计1.2 初始化函数Init详解

C++ 右值引用(rvalue references)与移动语义(move semantics)深度解析

《C++右值引用(rvaluereferences)与移动语义(movesemantics)深度解析》文章主要介绍了C++右值引用和移动语义的设计动机、基本概念、实现方式以及在实际编程中的应用,... 目录一、右值引用(rvalue references)与移动语义(move semantics)设计动机1

Nginx服务器部署详细代码实例

《Nginx服务器部署详细代码实例》Nginx是一个高性能的HTTP和反向代理web服务器,同时也提供了IMAP/POP3/SMTP服务,:本文主要介绍Nginx服务器部署的相关资料,文中通过代码... 目录Nginx 服务器SSL/TLS 配置动态脚本反向代理总结Nginx 服务器Nginx是一个‌高性

C++ move 的作用详解及陷阱最佳实践

《C++move的作用详解及陷阱最佳实践》文章详细介绍了C++中的`std::move`函数的作用,包括为什么需要它、它的本质、典型使用场景、以及一些常见陷阱和最佳实践,感兴趣的朋友跟随小编一起看... 目录C++ move 的作用详解一、一句话总结二、为什么需要 move?C++98/03 的痛点⚡C++

Go异常处理、泛型和文件操作实例代码

《Go异常处理、泛型和文件操作实例代码》Go语言的异常处理机制与传统的面向对象语言(如Java、C#)所使用的try-catch结构有所不同,它采用了自己独特的设计理念和方法,:本文主要介绍Go异... 目录一:异常处理常见的异常处理向上抛中断程序恢复程序二:泛型泛型函数泛型结构体泛型切片泛型 map三:文

详解C++ 存储二进制数据容器的几种方法

《详解C++存储二进制数据容器的几种方法》本文主要介绍了详解C++存储二进制数据容器,包括std::vector、std::array、std::string、std::bitset和std::ve... 目录1.std::vector<uint8_t>(最常用)特点:适用场景:示例:2.std::arra

C++构造函数中explicit详解

《C++构造函数中explicit详解》explicit关键字用于修饰单参数构造函数或可以看作单参数的构造函数,阻止编译器进行隐式类型转换或拷贝初始化,本文就来介绍explicit的使用,感兴趣的可以... 目录1. 什么是explicit2. 隐式转换的问题3.explicit的使用示例基本用法多参数构造

C++,C#,Rust,Go,Java,Python,JavaScript的性能对比全面讲解

《C++,C#,Rust,Go,Java,Python,JavaScript的性能对比全面讲解》:本文主要介绍C++,C#,Rust,Go,Java,Python,JavaScript性能对比全面... 目录编程语言性能对比、核心优势与最佳使用场景性能对比表格C++C#RustGoJavapythonjav