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 列表

CPRINTHELLO Procedure PrintHello__14HelloOperationFv Procedure CLMODULE Procedure CBLPRINTHELLO Procedure RPGMODULE Procedure
CPRINTHELLO( )   CLMODULE( ) CBLPRINTHELLO( ) RPGMODULE( )
CPRINTHELLO( )   CLMODULE( ) CBLPRINTHELLO( ) RPGMODULE( )
CALLPRC PRC(PRINTHELLO)   CALLPRC PRC(CLMODULE ) CALLPRC PRC(CBLPRINTHELLO) CALLPRC PRC(RPGMODULE)
CALL LINKAGE TYPE IS PROCEDURE 'CPRINTHELLO'   CALL LINKAGE TYPE IS PROCEDURE 'CLMODULE' CALL LINKAGE TYPE IS PROCEDURE 'CBLPRINTHELLO' CALL LINKAGE TYPE IS PROCEDURE 'RPGMODULE'
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。


下載

ile_sample.savf 11KB HTTP
關於下載方法的信息


 

參考資料

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章