我們可以通過以下幾種方式在 ILE 端調用 PASE 應用程序:
在 ILE 綠屏命令行直接調用 PASE 端可執行應用程序
QSH CMD('pase_command parameters')
pase_command 為 PASE 端的可執行應用程序,它可以是該可執行應用程序的絕對路徑,
也可以是當前 session 環境變量 PATH 下的可執行的應用程序。
清單 1. 使用 QSH CMD
QSH CMD('ps -ef')
QSH CMD('/QOpenSys/usr/bin/ls')
CALL QP2SHELL PARM('pase_command''parameters)
pase_command 為 PASE 端的可執行應用程序的絕對路徑 , parameters 為該命令的命令行
參數。例如 :
清單 2. 在命令行使用 QP2SHELL
CALL QP2SHELL PARM('/QOpenSys/usr/bin/ls' '/QOpenSys/QIBM')
在 ILE 程序中調用 PASE 端應用程序
在 ILE 程序中調用 PASE 端可執行應用程序 , 我們可以使用以下三個 API 實現在 ILE 程序中調用 PASE 端應用程序。
QP2SHELL
QP2SHELL2
QP2SHELL 和 QP2SHELL2 這兩個 API 提供了壹個非常簡單的使用 IBM i PASE 程序的
接口,直接使用要運行的 IBM i PASE 程序名字和輸入參數作為 API 的輸入,就可以調用 PASE 應用。
這兩個 API 參數相同,差別在於 QP2SHELL()函數會創建新的激活組並在其中運行 PASE 程序。而 QP2SHELL2()函數會在調用者相同的激活組中運行 PASE 程序。這兩個 API 都沒有指示錯誤狀態的返回值,也不會返回 PASE 程序的返回值。
程序示例:
清單 3. 在程序中使用 QP2SHELL
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <qp2usr.h>
#include <qp2shell.h>
void main(int argc, char* argv[])
{
char* parm = “/”;
char* pasePgm = “/QOpenSys/bin/ls”;
QP2SHELL(pasePGM, parm);
}
Qp2RunPase
Qp2RunPase 允許用戶提供更多的參數來對 PASE 程序的運行進行控制。它可以指定程
序名和運行參數,還可以定義 PASE 程序運行環境變量,以及 PASE 程序初始運行的 CCSID。Qp2RunPase 的返回值可以得到 PASE 程序執行的狀態。PASE 程序結束返回時,導致 Qp2RunPase 返回並將控制權返還給 ILE 代碼。下面是 Qp2RunPase 函數的原型:
清單 4. Qp2RunPase 函數聲明
int Qp2RunPase(
const char* pathname,
const char* symbolName, const void* symbolData,
unsigned int symbolDataLen,
int ccsid,
const char* const* argv,
const char* const* envp);
參數說明:
pathName 輸入參數:
表明 PASE 程序在 IFS 文件系統中的路徑,可以使絕對路徑,也可以是相對於作業當前路徑的相對路徑。
symbolName、symbolData、symbolDataLen 輸入參數
symbolName 參數必須定義為為壹個空指針; symbolData 和 symbolDataLen 參數通常被忽略。
CCSID 輸入參數:
這個參數確定 PASE 程序初始運行的 CCSID。系統會將參數數據從作業默認的 CCSID 轉換為對應的編碼。例如,CCSID 設定為 1208,表明使用 UTF-8 編碼。
argv 參數:
argv 指向壹個指針數組,該指針數組為 IBM i PASE 程序的參數表。第壹個參數是 PASE 程序的路徑名,該參數的值與參數 pathName 的值相同。
envp 參數:
envp 參數指向壹個指針數組,該指針數組用來定義 IBM i PASE 程序的環境變量。
Qp2RunPase 的返回值能夠提供更多的信息,以便用戶對 PASE 程序的運行狀態進行處理。通常情況下,“0”表示正常返回,非零值表明錯誤返回,如“QP2RUNPASE_ERROR(-1)”或“QP2RUNPASE_RETURN_NOEXIT(-2)”這兩個值表明函數本身的異常返回。IBM i 還提供了壹些宏來處理返回值,如下表所示:
表 1. 使用宏處理 Qp2RunPase 返回值
宏
含義
WIFEXITED(stat_val) 如果返回非零值,表明 Qp2RunPase 函數的執行過程有錯誤,需要調用下面的宏獲得錯誤的細節信息
WEXITSTATUS(stat_val) 當宏 WIFEXITED(stat_val) 返回非零值時,表明執行過程有錯誤。該宏會返回 PASE 程序的返回值
WIFSIGNALED(stat_val) 檢查 PASE 程序是否被 signal 異常終止
WTERMSIG(stat_val) 當宏 WIFSIGNALED(stat_val) 返回非零值時,表明執行過程被 signal 終止。這個宏確認具體收到的 signal number
程序示例:
清單 5. Qp2RunPase 函數使用實例
int rc = Qp2RunPase(“program/path/in/PASE”, NULL, NULL, 0, 819, (char**)&argv, NULL);
if (rc == QP2RUNPASE_ERROR || rc == QP2RUNPASE_RETURN_NOEXIT)
{
printf (“internal error”);
}
if (WIFEXITED(rc) != 0)
{
// Command exited normally, check its return code
paseRC = WEXITSTATUS(rc);
printf (“pase program exit with none zero return: %d”, paseRC);
}
在 ILE 程序中調用 PASE 函數
以上介紹了在 ILE 中調用 PASE 環境中的應用程序 IBM i 還提供了壹組支持直接調用 PASE ***享庫的 API。調用過程需要用到以下函數:
Qp2ptrsize: 獲取 PASE 的指針長度。PASE 支持 32 位模式和 64 位模式。
Qp2dlopen: 類似於 UNIX 下的 dlopen() 函數,用於打開 PASE ***享庫。
Qp2dlsym: 類似於 UNIX 下的 dlsym() 函數,用於查找對應的函數入口。
Qp2dlclose: 類似於 UNIX 下的 dlclose() 函數,用於關閉 PASE ***享庫。
Qp2dlerror: 如果 Qp2dlopen、Qp2dlsym 或 Qp2dlclose 函數在執行過程出錯,用戶可以使用這個函數獲取錯誤信息。
Qp2malloc: 在 PASE 中分配壹塊內存,*** ILE 與 PASE 之間進行數據交互。
Qp2free: 用於釋放 Qp2mallloc 函數分配的內存。
Qp2CallPase
Qp2CallPase 使得用戶可以在 ILE 程序中調用 PASE ***享庫中的函數。Qp2CallPase 不會產生新的任務,只會在當前任務中執行 PASE 函數。
清單 6. Qp2CallPase 函數原型
#include <qp2user.h>
int Qp2CallPase(
const void* target,
const void* arglist,
const QP2_arg_type_t* signature,
QP2_result_type_t result_type,
void* result);
參數說明:
target
PASE 函數的描述符。
arglist:
IBM i PASE 函數的參數列表。
signature
參數的具體類型。QP2_ARG_END 表示 Signature 列表的結尾,QP2_ARG_WORD 表示 4-byte 數據,QP2_ARG_FLOAT32 表示 4-byte 浮點型數據,QP2_ARG_FLOAT64 表示 8-byte 浮點型數據。
result_type
調用的 PASE 函數的返回值的類型,在頭文件 qp2user.h 中定義。QP2_RESULT_VOID 表明 PASE 函數沒有返回值,QP2_RESULT_WORD 表示 4-byte 數據,QP2_RESULT_DWORD 表示 8-byte 數據,QP2_RESULT_FLOAT64 表示 8-byte 浮點型數據。
result
PASE 函數的返回值。
下面介紹 Qp2CallPase 函數的使用方法和步驟:
初始化:調用 IBM i PASE 環境之前必須對其進行初始化。IBM i PASE 環境提供了兩個工具用來完成初始化,壹個是 /usr/bin/start32,用來激活 32 位 IBM i PASE 環境,另壹個是 /usr/bin/start64,用來激活 64 位 IBM i PASE 環境。每個 IBM i 進程必須且只能運行壹個獨立的 IBM iPASE 環境。
檢查:調用 Qp2ptrsize() 來確定 IBM i PASE 環境是否正常運行。返回值:
0,表示沒有完成初始化。
4,表示 PASE 環境運行在 32 位模式下
8,表示 PASE 環境運行在 64 位模式下。
加載庫:用 Qp2dlopen 和 Qp2dlsym 將被調用的庫加載至內存中,然後就可以定位被調用函數的入口。
調用 Qp2CallPase:使用 Qp2CallPase() API 激活 PASE ***享庫函數,被調用的函數參數列表以指針數組的方式傳遞給 Qp2CallPase。ILE代碼還需要提供壹種方式來描述參數列表的類型,通常稱為 Signature。用戶可以在頭文件 qsysinc/qp2usr.h 中找到這些類型定義。
終止 IBM i PASE 進程:需要先調用 Qp2dlclose() 來卸載 IBM i PASE ***享庫,然後調用 Qp2EndPase() 函數來終止 start64 或 start32 程序啟動的 PASE 環境。
清單 7. Qp2CallPase 函數使用實例
#include <stdio.h>
#include <qp2shell2.h>
#include <qp2user.h>
#define JOB_CCSID 0
int main(int argc, char* argv[])
{
QP2_ptr64_t id;
void* getpid_pase;
const QP2_arg_type_t signature[] = {QP2_ARG_END};
QP2_word_t result;
QP2SHELL2(“/usr/lib/start32”);
id = Qp2dlopen(NULL, QP2_RTLD_NOW, JOB_CCSID);
getpid_pase = Qp2dlsym(id, “getpid”, JOB_CCSID, NULL);
int rc = Qp2CallPase(getpid_pase,
NULL,// no argument list
signature,
QP2_RESULT_WORD,
&result)
printf (“IBM i PASE getpid() = &i\n”, result);
if (result == -1)
printf (“IBM i errno = %i\n”, *Qp2errnop());
Qp2dlclose(id);
Qp2EndPase();
return 0;
}
編譯 ILE 端程序生成可執行的 PGM
在 ILE 端我們通常通過 CRTCMOD(如果源程序文件是由 ILE C 語言編寫)或者 CRTCPPMOD(如果源程序文件是由 ILE C++ 語言編寫)命令來將 ILE 端的程序編譯成 MODULE,然後用 CRTPGM 來將編譯好的 MODULE(s) 以及 Service Program 鏈接生成可執行的 PGM。
清單 8. 在 ILE 編譯和鏈接程序
CRTCMOD MODULE(QYOURLIB/YOURMOD) SRCFILE(QYOURLIB/QCSRC)
或者:÷ CRTCPPMOD MODULE(QYOURLIB/YOURMOD)
SRCSTMF('/qopensys/myprogram/myprogram.cpp') INCDIR('/qopensys/myprogram/include')
CRTPGM PGM(QYOURLIB/YOURPGM) MODULE(QYOURLIB/YOURMOD)
BNDSVRPGM(QSYS/QP2USER)