在AS400(IBM i)操作系统中,每个对象都有Domain和State两个属性。有时候这两个属性不对,程序就会一些看似莫名其妙的问题。
Domain: 有两个系统值可以设置: *SYSTEM 和 *USER。 如果程序需要访问系统域的对象,那么这个程序的状态很重要,必须是 *SYSTEM 状态或者 *INHERENT 状态而又被一个 *SYSTEM 状态的程序调用。
State: 有三个系统值可以设置:*SYSTEM, *USER 和 *INHERENT。*USRE 状态的的程序只能访问 *USER 域的对象。
查看对象的Domain值和State值:
对于program,使用DSPPGM; 对于service program, 使用DSPSRVPGM.
如下图所示:
AS400: 对象属性Domain和State_编程
通过CL命令CHGOBJDMN可以修改一个对象的Domain和State值。
那么如果我们自己编写一个程序想调用系统提供的service program中定义的API,怎么办呢?
假如我写的程序叫做test.c, 要调用的service program是QSYS/QMYSRVPGM, 其Domain为*SYSTEM。
1. 在自己的程序中使用extern声明要调用的API。这里要注意这个API是C命名还是C++命名。
2. 编译Module: CRTCPPMOD MODULE(TESTLIB/TEST) SRCSTMF('/home/test.c') DBGVIEW(*ALL)
3. 创建Program: CRTPGM PGM(TESTLIB/TEST) MODULE(TESTLIB/TEST) BNDSRVPGM((QSYS/QMYSRVPGM))
这个时候我们的program TEST的状态为*USER, 不能够调用*SYSTEM状态的QMYSRVPGM中的API. 直接运行TEST会出错。
4. 改变program 的State值:CHGOBJDMN OBJ(TESTLIB/TEST) OBJTYPE(*PMG) OBJDMN(*SAME) RUNDMN(*SYS)
这个时候出错了,这个program中有一个Module,Module也是有状态的,需要改变Module的状态。
5. CHGOBJDMN OBJ(TESTLIB/TEST) OBJTYPE(*MODULE) OBJDMN(*SAME) RUNDMN(*SYS)
还需要用这个Module更新program
6. updpgm2 testlib/test testlib/test
这个时候program的状态也变成了*SYSTEM,可以调用service program中的API了。