【原创】OIOIC对象模型[v1.0]
时间:2008-01-16 11:14:18 来源: 作者:
|
[size=4] OIOIC ---- 简称OIC,专为C语言设计的软件对象模型 ---- 填补了C语言OO技术的空白,统一世界软件插件规范。 Oicos_v1.0.0 ---- 基于 OIOIC 的新一代操作系统 ---- Oicos ---- 的种子。[/size] 您可以用 OIOIC 描述花,鸟,草,虫,树木,房屋 ... ... 您可以用 OIOIC 描述分子,原子,质子,电子 ... ... 您可以用 OIOIC 描述地球,太阳,银河系,黑洞 ... ... 您可以用 OIOIC 描述 ... ... [ 本帖最后由 Pervise 于 2007-9-17 11:57 编辑 ] Oicos_v1.0.0_20070606.tar.gz Pervise 回复于:2007-07-26 00:21:34 [table=95%][tr][td][font=FixedSys]/** * * 文 件 名: OIOIC.h * * 描 述: OIOIC对象模型 .h 文件. * * 版 本: v1.0 * * 备 注: === 名词术语 === * 1. S: Space, 空间. 可执行程序, 静态库, 动态库都各是一个S. * 2. o或O, ob或OB, Obj或OBJ: 在没有歧义的情况下, 一般都指Object, 即对象. * 3. OM或M: Object Mold, 对象模. * 4. MSN: M Serial Number, M的序号. * 5. OSN: O Serial Number, O的序号. * 6. SID: S的ID. 只在OID(见下)中, 不单独存在. * 7. OID: O的ID. 前段是SID, 后段是OSN. * 8. OIN: O Identification Number, O的标识号. 只为通过OIN输出对象指针的对象编制OIN, 参阅OS的GetObject函数. * 9. EM: the Extended Member, 扩展成员. * 10. IC: Inheritance Chain, 继承链. * 11. Node或ND或N: the NoDe of IC, 继承链节点, 每个节点就是一个对象. 节点有LND, IND, FND三种. * 12. FND: First ND, 继承链的首节点, 一条IC至少有一个FND. * 13. IND: Inner ND, 继承链的内节点, 除FND和LND以外的都是IND, 一条IC可能会有多个IND, 也可能没有IND. * 14. LND: Last ND, 继承链的末节点, 一条IC有且只有一个LND. * 15. BN: Base Node, 基节点. * 16. IBN或IB: Immediate BN, 直接基节点. * 17. DN: Derived Node, 派生节点. * 18. IDN: Immediate DN, 直接派生节点. * 19. AO: Active Object, 活动对象. 只有线程是AO. * 20. BO: Base Object, 基对象. * 21. DO: Derived Object, 派生对象. * 22. GO: General Object, 一般对象, 即有边界的对象. * 23. SO: Super Object, 超级对象, 即没有边界的对象, 进程和线程就是SO. * 24. CR: CalleR, 来访者. 只有AO才能成为CR. * 25. CE: CalleE, 受访者. 任何对象都可做CE. * 26. CS: Caller's Seat, 来访者的坐位. * 27. VO: Visit Object, 访问对象, 即调用对象的接口. * 28. VR: Visiting Record, 来访记录. * 29. MR: MandatoR, CR的委托者, 即委托来访的CR去访问另一对象的对象, 规定只由非AO(非活动对象)做MR. MR * 不具有传递性, 比如, 对象A委托对象B去访问对象C, 那么对C来说A是B的MR; 如果在B访问C期间, C又让B去 * 访问D, 那么对D来说, C是B的MR, 但A不是B的MR. * 30. TOG: the function TOGgling object interface, 关联对象接口的函数, 简称TOG函数. * 31. CRT: the function CReaTing object , 创建对象的函数, 简称CRT函数. * 32. ACS: the Array of CS, ND的CS数组, 数组元素类型是VR. * 33. AND: the Array of ND, ND数组, 数组元素类型是OBJECT, 元素数量就是ND的数量.AND的第一个元素必 * 须是LND, 否则不能称为AND. * 34. ABN: the Array of BN, BN数组, 数组元素类型是对象指针. * 35. AIB: the Array of IB, IB数组, 数组元素类型是对象指针. 访问IB的顺序是从第0个到最后一个元素的顺序. * 36. AMS: the Array of MSN, MS数组, 数组元素类型是MSNTYP. * 37. IPF: Interface Private Function, 对象接口专用的函数. IPF的返回类型必须是IRESULT. 为了便于区别, IPF的 * 函数名前最好有前缀"IPF_". * 38. O_Ix: 封装了对象相应接口的共性操作的IPF, 是特殊的IPF, 调用位置在V.a规则(见下)里有特殊的规定. * 39. C规则: Create规则, 即对象创建规则, 也就是CRT函数的实现规则. 其中有, * a. 创建对象时, 除了IQ和OQ的数据空间以及EM内须动态分配的空间, 一次性连续地分配IC的其它空间, IQ和 * OQ的数据空间在创建对象时单独动态分配, EM内须动态分配的空间由ND在自己的Open接口里动态分配; * b. IC的内存空间的开头一段是AND空间. * 40. V规则: Visit规则, 即对象访问规则. 其中有, * a. 一般来讲, 接口须顺序完成三个工作: (1)按顺序访问每个IB; (2)调用自己的O_Ix函数; (3)执行接口自己的 * 任务.规定,Interact0接口的NTC_ISSEND和NTC_OSSEND交互只须做(2)和(3),Input和Output接口不能做(1), * 其它必须(1)(2)(3)全做. * b. 不可重入(Not Reentrant)访问对象, 即在接口的第一步工作中, 同一MR的同一CR对每个BN只能而且必须 * 访问一次. * 41. DNG缓冲: DaNGerous buffer, 危险缓冲. 为了节省内存空间, 可以开辟一块多处共用的缓冲, 如果这块缓冲 * 因多处公用而存在风险, 那么这样的缓冲就叫DNG缓冲, 即使这些风险最终确定已经消除. * 42. DNG函数: DaNGerous function, 危险函数, 也就是使用DNG缓冲的函数. 为了便于区别, DNG函数名前最好 * 有前缀"DNG_". * * === 说明 === * 1. SID必须是全球唯一的. * 2. OID必须是全球唯一的. * 3. 在同一S里, MSN必须互不相同. * 4. 为保证OID的全球唯一性, 在同一S里, OSN必须互不相同. * 5. 在任何S里, 如果OID值为0, 都是无效的OID. * 6. 创建一个对象, 就产生一条IC, 这个对象就是LND. * 7. IC如果有IQ那么只有一个IQ, 如果有OQ那么只有一个OQ. * 8. 当IC只有一个ND时, 那么这个ND即是FND又是LND. * 9. IC的每个ND必须遵守V规则. * 10. 在创建LND对象之前, 必须先知道IC内各ND的最少CS数量. * 11. 最少CS数量 = CR数量 * (最长派生路径的DN数量 + 1). * 12. 如果对象已没有空闲的CS, 那么新来的CR将被"拒之门外". * * === 多重继承层次图示例 === * * O N1 (FND) * / | * / | * ON2 O N3 O N4 * / / / * / / / * ON5 O N6 O N7 O N8 * / / / * / / / * O N9 O N10 O N11 * | / * | / * O N12 (LND) * * 现在假设创建了一个N12对象, 那么就产生了一条IC, N12是IC的LND, N1是IC的FND. * * 1. 对N6来说, * BN是N1,N2,N3; * IB是N2,N3; * DN是N9,N10,N12. * 2. IC内各ND的BN数量如下, * Node BN数量 * ---- ------- * N1(FND) 0 * N2 1 * N3 1 * N4 1 * N5 2 * N6 3 * N7 3 * N8 2 * N9 5 * N10 6 * N11 5 * N12(LND) 11 * * 3. 访问对象时必须遵守V规则, 如果某MR委托某CR访问LND, 那么访问路线是, * N1(FND)->N2->N5->N3->N6->N9->N4->N7->N10->N8->N11->N12(LND). * 4. 假设IC的CR数为n. 那么IC内各ND的最长派生路径的DN数量和最少CS数量如下, * Node 最长派生路径的DN数量 最少CS数量 * ---------- ------------------------ ------------- * N1(FND) 4 n*5 * N2 3 n*4 * N3 3 n*4 * N4 3 n*4 * N5 2 n*3 * N6 2 n*3 * N7 2 n*3 * N8 2 n*3 * N9 1 n*2 * N10 1 n*2 * N11 1 n*2 * N12(LND) 0 n * **/ #ifndef __OIOIC_H__ #define __OIOIC_H__ /* * * 名称: _INLINE_ * 描述: 为了方便兼容旧C版本(C99之前的, 如C89), 宏定义内联指示符. * 备注: 如果C版本是C99之前的, 如C89, 定义为空值即可. */ #define _INLINE_ inline /* * * 一级数据类型定义 */ typedef char SBITS8; typedef unsigned char UBITS8; typedef short SBITS16; typedef unsigned short UBITS16; typedef int SBITS32; typedef unsigned int UBITS32; typedef long long SBITS64; typedef unsigned long long UBITS64; typedef float FLOAT; typedef double DOUBLE; typedef void VOID; /* * * 二级数据类型定义 */ typedef UBITS8 BYTE; // 位元组类型. byt_, by_, pby_. typedef UBITS16 ACTION; // 行为类型. act_, ac_, pac_. typedef UBITS32 BYTKTY; //byBYTe,c(K)apaciTY and q(K)uantiTY'stype, 以Byte为单位的容量和数量类型. byk_,yk_,pyk_. typedef UBITS32 BITKTY; //byBIT,c(K)apaciTY and q(K)uantiTY's type,以Bit为单位的容量和数量类型. btk_, tk_,ptk_. typedef UBITS16 MLDSN; // MSN类型. msn_ typedef UBITS64 OBJID; // OID类型, 高48位是SID, 低16位是OSN. oid_ typedef UBITS16 OBJIN; // OIN类型. oin_ typedef UBITS32 REFCNT; // object's REFerence CouNT type, 对象的引用计数类型. rfc_. typedef UBITS32 MODES; // 模式集类型. mds_. typedef UBITS16 NUMCS; // the NUMber of CS type, CS的数量类型. ncs_. typedef UBITS16 NUMND; // the NUMber of ND type, ND的数量类型. nnd_. typedef UBITS16 NUMIB; // the NUMber of IB type, IB的数量类型. nib_. typedef UBITS16 NUMBN; // the NUMber of BN type, BN的数量类型. nbn_. typedef SBITS8 BOOL; // 布尔类型, 规定此类型数据只能有两个值: TRUE 或 FALSE (见下面 TRUE 和 FALSE 的定义). bol_, pbl_. typedef SBITS32 IRESULT; //对象接口执行结果的数据类型, 必须是有符号类型. typedef SBITS32 FRESULT; //函数(包括对象函数及非对象函数)执行结果的数据类型, 必须是有符号类型. /* * * Byte位数 */ #define BYTBITS 8 /* * * 获取x的大小, 以Byte为单位. */ #define SIZEOF(x) sizeof(x) /* * * 描述: MSN * 备注: 要求MSN从1开始顺序标号, 定义模板如下, * //>#define MSN_ 1 //MSN的起点. * #define MSN_XXX1 (MSN_ + 0) //Xxx1的MSN. * #define MSN_XXX2 (MSN_ + 1) //Xxx2的MSN. * #define MSN_XXX3 (MSN_ + 2) //Xxx3的MSN. * ... ... ... ... ... ... * #define MSN_XXXn (MSN_ + n-1) //Xxxn的MSN. */ #define MSN_ 1 //MSN的起点. /* * * 描述: 对象接口执行结果定义。 * 备注: === 定义模板 === * * ... ... ... ... ... ... * ... ... ... ... ... ... * #define IR_N_PVT_YYY_ (IR_N_PVT_XXX_ -x) //Yyy的私有N结果的起点。 * #define IR_N_XXX (IR_N_PVT_XXX_ - x + 1)//... * ... ... ... ... ... ... * #define IR_N_XXX (IR_N_PVT_XXX_ -1) //... * #define IR_N_XXX (IR_N_PVT_XXX_ -0) //... * //>#define IR_N_PVT_XXX_ (IR_N_PVT_ -z) //Xxx的私有N结果的起点。 * // * // XXX对象模的私有N结果: * // * #define IR_N_PVT_XXX_ (IR_N_PVT_-x) //Xxx的私有N结果的起点。 * #define IR_N_XXX (IR_N_PVT_ - x + 1) //... * ... ... ... ... ... ... * #define IR_N_XXX (IR_N_PVT_ -1) //... * #define IR_N_XXX (IR_N_PVT_ -0) //... * //>#define IR_N_PVT_ (IR_N_PRIVATE_ -z) //<外部私有N结果的起点> * // * //非一个对象模专用的N结果: * // * //非一个对象模专用的P结果: * // * //>#define IR_P_PVT_ (IR_P_PRIVATE_ + z) // <外部私有P结果的起点> * #define IR_P_XXX (IR_P_PVT_ + 0) //... * #define IR_P_XXX (IR_P_PVT_ + 1) //... * ... ... ... ... ... ... * #define IR_P_XXX (IR_P_PVT_ + x - 1) //... * #define IR_P_PVT_XXX_ (IR_P_PVT_ + x) // Xxx的私有P结果的起点。 * // * // XXX对象模的私有P结果: * // * //>#define IR_P_PVT_XXX_ (IR_P_PVT_ +z) // Xxx的私有P结果的起点。 * #define IR_P_XXX (IR_P_PVT_XXX_ + 0) //... * #define IR_P_XXX (IR_P_PVT_XXX_ + 1) //... * ... ... ... ... ... ... * #define IR_P_XXX (IR_P_PVT_XXX_ + x - 1) //... * #define IR_P_PVT_YYY_ (IR_P_PVT_XXX_ + x) // Yyy的私有P结果的起点。 * ... ... ... ... ... ... * ... ... ... ... ... ... * */ #define IR_N_PVT_ (IR_N_PRIVATE_ - 50) // <外部私有N结果的起点> #define IR_N_UNSHARED (FR_N_PRIVATE_ - 1) //Open, 对象是非共享的. #define IR_N_FULL (FR_N_PRIVATE_ - 0) //Open,对象引用已满,不能再打开。 //>#define IR_N_PRIVATE_ (IR_N - z) // <内部私有N结果的起点> #define IR_N_PRIVATE_ (IR_N - 10) // <内部私有N结果的起点> #define IR_N_INVALIDARG (IR_N -1) //无效参数 #define IR_N __FR_ON__ //N结果(否定性结果)的起点. #define __IR_ON__ (IR_O - 5) //O结果域的N界. #define IR_O_NOPEN (IR_O - 2) //Close,对象还没有被打开. #define IR_O_VAINLY (IR_O -1) //空操作 #define IR_O 0 //O结果(中立性结果)域的中点。 #define IR_O_RELAY (IR_O + 1) //O接力 #define __IR_OP__ (IR_O + 5) //O结果域的P界. #define IR_P __FR_OP__ //P结果(肯定性结果)的起点. #define IR_P_RELAY (IR_P + 1) // P接力, O_Ix专用. #define IR_P_PRIVATE_ (IR_P + 10) // <内部私有P结果的起点> //>#define IR_P_PRIVATE_ (IR_P + z) // <内部私有P结果的起点> #define IR_P_IAEND (IR_P_PRIVATE_ + 0) //Interact0~3, 交互结束(InterActionENDs). #define IR_P_RCZERO (IR_P_PRIVATE_ + 1) //Close, 对象引用计数变为0. #define IR_P_PVT_ (IR_P_PRIVATE_ + 50) // <外部私有P结果的起点> /* * * 描述: 对象接口执行结果否定性/中立性/肯定性检测定义。 * 备注: NIR --- Negative IRESULT; * OIR --- O IRESULT; * PIR --- Positive IRESULT. */ #define NIR(Result) ( (IRESULT)(Result) <= __IR_ON__ ) #define OIR(Result) (((IRESULT)(Result)>__IR_ON__) &&((IRESULT)(Result) <__IR_OP__) ) #define PIR(Result) ( (IRESULT)(Result) >= __IR_OP__ ) /* * * 描述: 函数(包括对象函数及非对象函数)执行结果定义。 * 备注: === 定义模板 === * * ... ... ... ... ... ... * ... ... ... ... ... ... * #define FR_N_PVT_YYY_ (FR_N_PVT_XXX_ -x) //Yyy的私有N结果的起点。 * #define FR_N_XXX (FR_N_PVT_XXX_ - x + 1)//... * ... ... ... ... ... ... * #define FR_N_XXX (FR_N_PVT_XXX_ -1) //... * #define FR_N_XXX (FR_N_PVT_XXX_ -0) //... * //>#define FR_N_PVT_XXX_ (FR_N_PVT_ -z) //Xxx的私有N结果的起点。 * // * // XXX函数的私有N结果: * // * #define FR_N_PVT_XXX_ (FR_N_PVT_-x) //Xxx的私有N结果的起点。 * #define FR_N_XXX (FR_N_PVT_ - x + 1) //... * ... ... ... ... ... ... * #define FR_N_XXX (FR_N_PVT_ -1) //... * #define FR_N_XXX (FR_N_PVT_ -0) //... * //>#define FR_N_PVT_ (FR_N_PRIVATE_ -z) //<外部私有N结果的起点> * // * //非一个函数专用的N结果: * // * //非一个函数专用的P结果: * // * //>#define FR_P_PVT_ (FR_P_PRIVATE_ + z) // <外部私有P结果的起点> * #define FR_P_XXX (FR_P_PVT_ + 0) //... * #define FR_P_XXX (FR_P_PVT_ + 1) //... * ... ... ... ... ... ... * #define FR_P_XXX (FR_P_PVT_ + x - 1) //... * #define FR_P_PVT_XXX_ (FR_P_PVT_ + x) // Xxx的私有P结果的起点。 * // * // XXX函数的私有P结果: * // * //>#define FR_P_PVT_XXX_ (FR_P_PVT_ +z) // Xxx的私有P结果的起点。 * #define FR_P_XXX (FR_P_PVT_XXX_ + 0) //... * #define FR_P_XXX (FR_P_PVT_XXX_ + 1) //... * ... ... ... ... ... ... * #define FR_P_XXX (FR_P_PVT_XXX_ + x - 1) //... * #define FR_P_PVT_YYY_ (FR_P_PVT_XXX_ + x) // Yyy的私有P结果的起点。 * ... ... ... ... ... ... * ... ... ... ... ... ... * */ #define FR_N_PVT_ (FR_N_PRIVATE_ - 50) // <外部私有N结果的起点> #define FR_N_LOST (FR_N_PRIVATE_-0) //EnQueue/DeQueue,已丢失了Byte. //>#define FR_N_PRIVATE_ (FR_N - z) // <内部私有N结果的起点> #define FR_N_PRIVATE_ (FR_N - 10) // <内部私有N结果的起点> #define FR_N_INVALIDARG (FR_N -1) //无效参数. #define FR_N __FR_ON__ //N结果(否定性结果)的起点. #define __FR_ON__ (FR_O - 5) //O结果域的N界. #define FR_O_VAINLY (FR_O - 1) //空操作 #define FR_O 0 //O结果(中立性结果)域的中点。 #define FR_O_RELAY (FR_O + 1) //接力 #define __FR_OP__ (FR_O + 5) //O结果域的P界. #define FR_P __FR_OP__ //P结果(肯定性结果)的起点. #define FR_P_PRIVATE_ (FR_P + 10) // <内部私有P结果的起点> //>#define FR_P_PRIVATE_ (FR_P + z) // <内部私有P结果的起点> #define FR_P_HASVR (FR_P_PRIVATE_ + 0) //CallerCome,已经有这个VR了. #define FR_P_PVT_ (FR_P_PRIVATE_ + 50) // <外部私有P结果的起点> /* * * 描述: 函数(包括对象函数及非对象函数)执行结果否定性/中立性/肯定性检测定义。 * 备注: NFR --- Negative FRESULT; * OFR --- O FRESULT; * PFR --- Positive FRESULT. * */ #define NFR(Result) ( (FRESULT)(Result) <= __FR_ON__ ) #define OFR(Result) (((FRESULT)(Result)>__FR_ON__) &&((FRESULT)(Result) <__FR_OP__) ) #define PFR(Result) ( (FRESULT)(Result) >= __FR_OP__ ) /* * * 描述: 通用模式定义。 * 备注: 可定义 SIZEOF(MODES)*BYTBITS 个通用模式. 即如下, * * #define MOD_ 1 * #define MOD_XXX0 ( MOD_<< 0 ) //BIT0.1: xxx; 0: xxx。 * #define MOD_XXX1 (MOD_ << 1 ) // BIT1. 1: xxx; 0:xxx。 * #define MOD_XXX2 ( MOD_ << 2) //BIT2.1: xxx; 0: xxx。 * ... ... ... ... ... ... * #define MOD_XXXn (MOD_ <<(SIZEOF(MODES)*BYTBITS-1)) // BITn. 1: xxx;0: xxx。 */ #define MOD_ 1 #define MOD_SHARED (MOD_ << 0 ) // BIT0. 1: 共享; 0: 非共享。 #define MOD_BLOCKI (MOD_ << 1 ) //BIT1. 1: 阻断输入; 0:非阻断输入。只适用于Input接口。 #define MOD_BLOCKO (MOD_ << 2 ) //BIT2. 1: 阻断输出; 0: 非阻断输出。只适用于Output接口。 /* * * 描述: 对象交互行为分类定义。 * 备注: 1.从是否须要输入Byte流和有没有输出Byte流的角度,可将行为分为四种: * AC0 : 不需输入Byte流也没有输出Byte流; * AC1 : 不需要输入Byte流但有输出Byte流; * AC2 : 需要输入Byte流但没有输出Byte流; * AC3 : 即需要输入Byte流也有输出Byte流. * 2. 有时, 对象间交互需要输入Byte数据流或交互后有Byte数据流输出, 或者即需要 * 输入Byte数据流又有Byte数据流输出. 输入的数据流的类型必须是已知的, 但输 * 出的数据流类型可以是未知的. * TBSI: the Type of Byte Stream Inputed, 输入Byte数据流类型. * TBSO: the Type of Byte Stream Outputed, 输出Byte数据流类型. */ #define AC0 0 #define AC1 (1 << (SIZEOF(ACTION)*BYTBITS - 2)) #define AC2 (2 << (SIZEOF(ACTION)*BYTBITS - 2)) #define AC3 (3 << (SIZEOF(ACTION)*BYTBITS - 2)) /* 判断交互行为种类的mask */ #define ACMASK (3 << (SIZEOF(ACTION)*BYTBITS - 2)) [/font][/td][/tr][/table] [ 本帖最后由 Pervise 于 2007-7-26 00:54 编辑 ] Pervise 回复于:2007-07-26 00:41:09 [table=95%][tr][td][font=FixedSys]/* * * 描述: 对象交互行为定义。 * 备注: === 定义模板 === * * // * // 非一个对象模专用的交互行为: * // * //>#define ACT_PVT_ (ACT_ + z) // <外部私有交互行为的起点> * #define XXX_YYYYY (ACx | (ACT_PVT_ + 0)) //... * #define XXX_YYYYY (ACx | (ACT_PVT_ + 1)) //... * ... ... ... ... ... ... * #define XXX_YYYYY (ACx | (ACT_PVT_ + x - 1)) //... * #define ACT_PVT_XXX_ (ACT_PVT_ + x) //Xxx的私有交互行为的起点。 * // * // XXX对象模专用的交互行为: * // * //>#define ACT_PVT_XXX_ (ACT_PVT_ + z) //Xxx的私有交互行为的起点。 * #define XXX_YYYYY (ACx | (ACT_PVT_XXX_ + 0)) //... * #define XXX_YYYYY (ACx | (ACT_PVT_XXX_ + 1)) //... * ... ... ... ... ... ... * #define XXX_YYYYY (ACx | (ACT_PVT_XXX_ + x - 1)) //... * #define ACT_PVT_YYY_ (ACT_PVT_XXX_ + x) //Yyy的私有交互行为的起点。 * ... ... ... ... ... ... */ #define ACT_ 0 #define ASK_SHARED (AC0 | (ACT_ + 0)) // 问对象共享么。 #define SET_SHARED (AC0 | (ACT_ + 1)) // 设置对象共享。 #define SET_UNSHARED (AC0 | (ACT_ + 2)) // 设置对象非共享。 #define SET_BLOCKI (AC0 | (ACT_ + 3)) // 设置对象阻断输入。 #define SET_UNBLOCKI (AC0 | (ACT_ + 4)) // 设置对象非阻断输入。 #define SET_BLOCKO (AC0 | (ACT_ + 5)) // 设置对象阻断输出。 #define SET_UNBLOCKO (AC0 | (ACT_ + 6)) // 设置对象非阻断输出。 #define GET_IQCTY (AC1 | (ACT_ + 7)) // 获取IQ容量。 #define SET_IQCTY (AC2 | (ACT_ + 8)) // 设置IQ容量。 #define GET_OQCTY (AC1 | (ACT_ + 9)) // 获取OQ容量。 #define SET_OQCTY (AC2 | (ACT_ + 10)) // 设置OQ容量。 #define NTC_ISSEND (AC0 | (ACT_ + 11)) // NoTiCe(通知), the Input of Stream Section ENDs, 数据流段输入结束。 #define NTC_OSSEND (AC0 | (ACT_ + 12)) // NoTiCe(通知), the Onput of Stream Section ENDs, 数据流段输出结束。 #define ACT_PVT_ (ACT_ + 50) // <外部私有交互行为的起点> /* * * 定义布尔值和空指针值。 */ #ifdef FALSE #undef FALSE #endif #define FALSE 0 // 布尔类型数据值: 假 #ifdef TRUE #undef TRUE #endif #define TRUE 1 // 布尔类型数据值: 真 #define NULLP 0 // 0 值, 只用于指针. /*==========================+ OIOIC +==========================*/ /* * * 描述: 队列结构体 * 备注: q_, pq_. */ typedef struct TAG_QUEUE { BYTE* Dtrm; // Data Room, 数据空间。 BYTKTY Cty; //Dtrm的容量. BYTE* Front; //当前第一个Byte数据的地址。 BYTE* Rear; //当前最后一个Byte数据的地址的下一个Byte(当当前最后Byte数据在Dtrm的最后Byte时,其不属于Dtrm)的地址。 BYTKTY Qty; //当前Dtrm内存有的Byte数量。 BYTKTY Lost; //因Dtrm已满而丢弃的Byte数量。 }QUEUE; /* * * 描述: VR结构体. * 备注: vr_, pvr_. */ typedef struct TAG_VR { OBJID cr; // CR的ID. OBJID mr; // MR的ID. }VR; /* * * 描述: 定义 EM 数据类型. * 备注: 1. em_, pem_; * 2. 对象的实际扩展成员应该封装在EM结构体里, 定义格式如下, * typedef struct TAG_EM_XXX * { * //YYY yyy1; //成员yyy1. * //YYY yyy2; //成员yyy2. * //YYY yyy3; //成员yyy3. * //... * //YYY yyyn; //成员yyyn. * }EM_XXX; */ typedef VOID EM; // 定义EM数据类型. /* * * 描述: OIOIC对象模型结构体. * 备注: 名称是OIOIC的5个通用接口(Open、Input、Output、Interact、Close)的第一个字符的合写。 */ typedef struct TAG_OBJECT { /* RefCnt, 对象引用计数 ( Reference Count )。*/ REFCNT RefCnt; /* MSN, 模的SN.*/ MLDSN MSN; /* OID, 对象的ID. */ OBJID OID; /* Modes, 模式集。*/ MODES Modes; /* pq_IQ, 指向输入队列 */ QUEUE* pq_IQ; /* pq_OQ, 指向输出队列 */ QUEUE* pq_OQ; /* 为了... 需要下面两个成员: * po_AND: 指向AND. * NND: the Number of ND, ND数量, 也就是AND的元素数量. */ struct TAG_OBJECT* po_AND; NUMND NND; /* 为遵守V.a规则, 需要下面两个成员: * ppo_AIB: 指向AIB数组. * NIB: the Number of IB, IB数量, 即AIB的元素数量. */ struct TAG_OBJECT** ppo_AIB; NUMIB NIB; /* 为了能访问BN的EM和高效地清除来访记录, 需要下面两个成员: * ppo_ABN: 指向ABN数组. * NBN: the Number of BN, BN数量, 即ABN的元素数量. */ struct TAG_OBJECT** ppo_ABN; NUMBN NBN; /* 为遵守V.b规则, 需要下面两个成员: * pvr_ACS: 指向ACS. * NCS: the Number of CS, CS的数量, 即ACS的元素数量. */ VR* pvr_ACS; NUMCS NCS; /* 对象接口: Open, Input, Output, Interact0~3, Close 。*/ /*名称: Open * 描述: 打开. * 参数: pCaller --- [IN] 来访者. */ IRESULT (*Open) (struct TAG_OBJECT* This, const VR* pCaller); /*名称: Input * 描述: 输入. * 参数: IStrm --- [IN] 输入流; * Qty --- [IN] 输入的Byte数量; * pCaller --- [IN] 来访者. */ IRESULT (*Input) (struct TAG_OBJECT* This, BYTE* IStrm, BYTKTY Qty, const VR* pCaller); /*名称: Output * 描述: 输出. * 参数: OStrm --- [OUT] 输出流的流向; * Cty --- [IN] OStrm所指存储空间的容量; * pQty --- [OUT] 指向实际输出的Byte数量; * pCaller --- [IN] 来访者. */ IRESULT (*Output) (struct TAG_OBJECT* This, BYTE* OStrm, BYTKTY Cty, BYTKTY* pQty, const VR* pCaller); /*名称: Interact0 * 描述: 交互, 接收AC0类型的行为. * 参数: Act --- [IN] 交互行为; * pCaller --- [IN] 来访者. */ IRESULT (*Interact0) (struct TAG_OBJECT* This, ACTION Act, const VR* pCaller); /*名称: Interact1 * 描述: 交互, 接收AC1类型的行为. * 参数: Act --- [IN] 交互行为; * OStrm --- [OUT] 输出流的流向; * Cty --- [IN] OStrm所指存储空间的容量; * pQty --- [OUT] 指向实际输出的Byte数量; * pCaller --- [IN] 来访者. */ IRESULT (*Interact1) (struct TAG_OBJECT* This, ACTION Act, BYTE* OStrm, BYTKTY Cty, BYTKTY* pQty, const VR* pCaller); /*名称: Interact2 * 描述: 交互, 接收AC2类型的行为. * 参数: Act --- [IN] 交互行为; * IStrm --- [IN] 输入流; * Qty --- [IN] 输入的Byte数量; * pCaller --- [IN] 来访者. */ IRESULT (*Interact2) (struct TAG_OBJECT* This, ACTION Act, BYTE* IStrm, BYTKTY Qty, const VR* pCaller); /*名称: Interact3 * 描述: 交互, 接收AC3类型的行为. * 参数: Act --- [IN] 交互行为; * IStrm --- [IN] 输入流; * Qty --- [IN] 输入的Byte数量; * OStrm --- [OUT] 输出流的流向; * Cty --- [IN] OStrm所指存储空间的容量; * pQty --- [OUT] 指向实际输出的Byte数量; * pCaller --- [IN] 来访者. */ IRESULT (*Interact3) (struct TAG_OBJECT* This, ACTION Act, BYTE* IStrm, BYTKTY Qty, BYTE* OStrm, BYTKTY Cty, BYTKTY* pQty, const VR* pCaller); /*名称: Close * 描述: 关闭. * 参数: pCaller --- [IN] 来访者. */ IRESULT (*Close) (struct TAG_OBJECT* This, const VR* pCaller); /* pEM, 指向对象的EM(扩展成员)。*/ EM* pEM; }OBJECT; /*=======================+ 宏封装单个Byte出入列 +=======================*/ /* PLACE: 放入模式, 如果队列已满就丢弃这个Byte; * PUSH: 推入模式, 即使队列已满也推入这个Byte, 把第一个Byte挤出扔掉. */ /* * * 名称: Q_PLACE_BYTE * 描述: 宏, 向队列放入一个Byte. * 参数: pQ --- [IN] QUEUE类型指针, 指向队列; * byte --- [IN] 入列的Byte. */ #define Q_PLACE_BYTE(pQ, byte) do{ if((pQ)->Qty < (pQ)->Cty) { if((pQ)->Rear == (pQ)->Dtrm + (pQ)->Cty) (pQ)->Rear = (pQ)->Dtrm; *((pQ)->Rear) = (byte); (pQ)->Qty++; (pQ)->Rear++; }else (pQ)->Lost++; }while(0) /* * * 名称: Q_PUSH_BYTE * 描述: 宏, 向队列推入一个Byte. * 参数: pQ --- [IN] QUEUE类型指针, 指向队列; * byte --- [IN] 入列的Byte. */ #define Q_PUSH_BYTE(pQ, byte) do{ if((pQ)->Qty < (pQ)->Cty) { if((pQ)->Rear == (pQ)->Dtrm + (pQ)->Cty) (pQ)->Rear = (pQ)->Dtrm; *((pQ)->Rear) = (byte); (pQ)->Qty++; (pQ)->Rear++; }else { (pQ)->Rear = (pQ)->Front; *((pQ)->Rear) = (byte); if( (pQ)->Front == ((pQ)->Dtrm + (pQ)->Cty -1) ) (pQ)->Front = (pQ)->Dtrm; else (pQ)->Front++; (pQ)->Lost++; } }while(0) /*===================+ 实现并向外声明VO及VVO函数 +====================*/ /* 注意: VVO_Xxxx只在O_IX_中使用, O_IX_的定义见下面. */ // // 先声明CallerCome和CallerLeave函数: // extern FRESULT CallerCome(OBJECT* pND, const VR* pCaller); extern FRESULT CallerLeave(OBJECT* pND, const VR* pCaller); /** * * 名称: VO_Open, VVO_Open * 描述: 接口Open的VO及VVO函数. * 参数: pObject --- [IN] 指向对象; * pCaller --- [IN] 来访者. * 备注: VVO_Open只在O_IX_中使用. */ static _INLINE_ IRESULT VO_Open(OBJECT* pObject, const VR* pCaller) { IRESULT ir = IR_O; if( FR_P == CallerCome(pObject, pCaller) ) { ir = pObject->Open(pObject, pCaller); CallerLeave(pObject, pCaller); }else { ir = IR_O_VAINLY; } return ir; } static _INLINE_ IRESULT VVO_Open(OBJECT* pObject, const VR* pCaller) { IRESULT ir = IR_O; if( FR_P == CallerCome(pObject, pCaller) ) ir = pObject->Open(pObject, pCaller); else ir = IR_O_VAINLY; return ir; } /** * * 名称: VO_Input * 描述: 接口Input的VO函数. * 参数: pObject --- [IN] 指向对象; * IStrm --- [IN] 输入流; * Qty --- [IN] 输入的Byte数量; * pCaller --- [IN] 来访者. * 备注: 接口Input没有VVO_Input函数. */ static _INLINE_ IRESULT VO_Input(OBJECT* pObject, BYTE* IStrm, BYTKTY Qty, const VR* pCaller) { IRESULT ir = IR_O; if( FR_P == CallerCome(pObject, pCaller) ) { ir = pObject->Input(pObject, IStrm, Qty, pCaller); CallerLeave(pObject, pCaller); }else { ir = IR_O_VAINLY; } return ir; } /** * * 名称: VO_Output * 描述: 接口Output的VO函数. * 参数: pObject --- [IN] 指向对象; * OStrm --- [OUT] 输出流的流向; * Cty --- [IN] OStrm所指存储空间的容量; * pQty --- [OUT] 指向实际输出的Byte数量; * pCaller --- [IN] 来访者. * 备注: 接口Output没有VVO_Output函数. */ static _INLINE_ IRESULT VO_Output(OBJECT* pObject, BYTE* OStrm, BYTKTY Cty, BYTKTY* pQty, const VR* pCaller) { IRESULT ir = IR_O; if( FR_P == CallerCome(pObject, pCaller) ) { ir = pObject->Output(pObject, OStrm, Cty, pQty, pCaller); CallerLeave(pObject, pCaller); }else { ir = IR_O_VAINLY; } return ir; } /** * * 名称: VO_Interact0, VVO_Interact0 * 描述: 接口Interact0的VO及VVO函数. * 参数: pObject --- [IN] 指向对象; * Act --- [IN] 交互行为; * pCaller --- [IN] 来访者. * 备注: VVO_Interact0只在O_IX_中使用. */ static _INLINE_ IRESULT VO_Interact0(OBJECT* pObject, ACTION Act, const VR* pCaller) { IRESULT ir = IR_O; if( FR_P == CallerCome(pObject, pCaller) ) { ir = pObject->Interact0(pObject, Act, pCaller); CallerLeave(pObject, pCaller); }else { ir = IR_O_VAINLY; } return ir; } static _INLINE_ IRESULT VVO_Interact0(OBJECT* pObject, ACTION Act, const VR* pCaller) { IRESULT ir = IR_O; if( FR_P == CallerCome(pObject, pCaller) ) ir = pObject->Interact0(pObject, Act, pCaller); else ir = IR_O_VAINLY; return ir; } /** * * 名称: VO_Interact1, VVO_Interact1 * 描述: 接口Interact1的VO及VVO函数. * 参数: pObject --- [IN] 指向对象; * Act --- [IN] 交互行为; * OStrm --- [OUT] 输出流的流向; * Cty --- [IN] OStrm所指存储空间的容量; * pQty --- [OUT] 指向实际输出的Byte数量; * pCaller --- [IN] 来访者. * 备注: VVO_Interact1只在O_IX_中使用. */ static _INLINE_ IRESULT VO_Interact1(OBJECT* pObject, ACTION Act, BYTE* OStrm, BYTKTY Cty, BYTKTY* pQty, const VR* pCaller) { IRESULT ir = IR_O; if( FR_P == CallerCome(pObject, pCaller) ) { ir = pObject->Interact1(pObject, Act, OStrm, Cty, pQty, pCaller); CallerLeave(pObject, pCaller); }else { ir = IR_O_VAINLY; } return ir; } static _INLINE_ IRESULT VVO_Interact1(OBJECT* pObject, ACTION Act, BYTE* OStrm, BYTKTY Cty, BYTKTY* pQty, const VR* pCaller) { IRESULT ir = IR_O; if( FR_P == CallerCome(pObject, pCaller) ) ir = pObject->Interact1(pObject, Act, OStrm, Cty, pQty, pCaller); else ir = IR_O_VAINLY; return ir; } /** * * 名称: VO_Interact2, VVO_Interact2 * 描述: 接口Interact2的VO及VVO函数. * 参数: pObject --- [IN] 指向对象; * Act --- [IN] 交互行为; * IStrm --- [IN] 输入流; * Qty --- [IN] 输入的Byte数量; * pCaller --- [IN] 来访者. * 备注: VVO_Interact2只在O_IX_中使用. */ static _INLINE_ IRESULT VO_Interact2(OBJECT* pObject, ACTION Act, BYTE* IStrm, BYTKTY Qty, const VR* pCaller) { IRESULT ir = IR_O; if( FR_P == CallerCome(pObject, pCaller) ) { ir = pObject->Interact2(pObject, Act, IStrm, Qty, pCaller); CallerLeave(pObject, pCaller); }else { ir = IR_O_VAINLY; } return ir; } static _INLINE_ IRESULT VVO_Interact2(OBJECT* pObject, ACTION Act, BYTE* IStrm, BYTKTY Qty, const VR* pCaller) { IRESULT ir = IR_O; if( FR_P == CallerCome(pObject, pCaller) ) ir = pObject->Interact2(pObject, Act, IStrm, Qty, pCaller); else ir = IR_O_VAINLY; return ir; } /** * * 名称: VO_Interact3, VVO_Interact3 * 描述: 接口Interact3的VO及VVO函数. * 参数: pObject --- [IN] 指向对象; * Act --- [IN] 交互行为; * IStrm --- [IN] 输入流; * Qty --- [IN] 输入的Byte数量; * OStrm --- [OUT] 输出流的流向; * Cty --- [IN] OStrm所指存储空间的容量; * pQty --- [OUT] 指向实际输出的Byte数量; * pCaller --- [IN] 来访者. * 备注: VVO_Interact3只在O_IX_中使用. */ static _INLINE_ IRESULT VO_Interact3(OBJECT* pObject, ACTION Act, BYTE* IStrm, BYTKTY Qty, BYTE* OStrm, BYTKTY Cty, BYTKTY* pQty, const VR* pCaller) { IRESULT ir = IR_O; if( FR_P == CallerCome(pObject, pCaller) ) { ir = pObject->Interact3(pObject, Act, IStrm, Qty, OStrm, Cty, pQty, pCaller); CallerLeave(pObject, pCaller); }else { ir = IR_O_VAINLY; } return ir; } static _INLINE_ IRESULT VVO_Interact3(OBJECT* pObject, ACTION Act, BYTE* IStrm, BYTKTY Qty, BYTE* OStrm, BYTKTY Cty, BYTKTY* pQty, const VR* pCaller) { IRESULT ir = IR_O; if( FR_P == CallerCome(pObject, pCaller) ) ir = pObject->Interact3(pObject, Act, IStrm, Qty, OStrm, Cty, pQty, pCaller); else ir = IR_O_VAINLY; return ir; } /** * * 名称: VO_Close, VVO_Close * 描述: 接口Close的VO及VVO函数. * 参数: pObject --- [IN] 指向对象; * pCaller --- [IN] 来访者. * 备注: VVO_Close只在O_IX_中使用. */ static _INLINE_ IRESULT VO_Close(OBJECT* pObject, const VR* pCaller) { IRESULT ir = IR_O; if( FR_P == CallerCome(pObject, pCaller) ) { ir = pObject->Close(pObject, pCaller); CallerLeave(pObject, pCaller); }else { ir = IR_O_VAINLY; } return ir; } static _INLINE_ IRESULT VVO_Close(OBJECT* pObject, const VR* pCaller) { IRESULT ir = IR_O; if( FR_P == CallerCome(pObject, pCaller) ) ir = pObject->Close(pObject, pCaller); else ir = IR_O_VAINLY; return ir; } /*======================+ 定义各接口的 O_IX_ +=======================*/ /* O_IX_ 是 OBJECT_<INTERFACE>_ 型的宏, 这些封装了对象相应接口的前面通用部分. */ // // 先声明 O_Ix 函数: // extern IRESULT Object_Open(OBJECT* This, const VR* pCaller); extern IRESULT Object_Input(OBJECT* This, BYTE* IStrm, BYTKTY Qty, const VR* pCaller); extern IRESULT Object_Output(OBJECT* This, BYTE* OStrm, BYTKTY Cty, BYTKTY* pQty, const VR* pCaller); extern IRESULT Object_Interact0(OBJECT* This, ACTION Act, const VR* pCaller); extern IRESULT Object_Interact1(OBJECT* This, ACTION Act, BYTE* OStrm, BYTKTY Cty, BYTKTY* pQty, const VR* pCaller); extern IRESULT Object_Interact2(OBJECT* This, ACTION Act, BYTE* IStrm, BYTKTY Qty, const VR* pCaller); extern IRESULT Object_Interact3(OBJECT* This, ACTION Act, BYTE* IStrm, BYTKTY Qty, BYTE* OStrm, BYTKTY Cty, BYTKTY* pQty, const VR* pCaller); extern IRESULT Object_Close(OBJECT* This, const VR* pCaller); /* * * 名称: OBJECT_OPEN_ * 描述: 宏, Open接口的O_IX_. * 备注: 实现了V.a规则的访问IB, 调用O_Ix的部分. */ #define OBJECT_OPEN_ do{ NUMIB i; VR Caller; IRESULT ir = IR_O; if( 0 == (This->RefCnt+1) ) return IR_N_FULL; Caller.cr = pCaller->cr; Caller.mr = This->OID; if( This->RefCnt > 0) { if( MOD_SHARED & This->Modes ) { for(i=0; i<This->NIB; i++) { ir = VO_Interact0(*(This->ppo_AIB+i), ASK_SHARED, &Caller); if( NIR(ir) ) return IR_N_UNSHARED; } }else { return IR_N_UNSHARED; } This->RefCnt++; return IR_P; } for(i=0; i<This->NIB; i++) { ir = VVO_Open(*(This->ppo_AIB+i), pCaller); if( NIR(ir) ) { NUMIB j; for( j = 0; j<i; j++) VO_Close(*(This->ppo_AIB+j), &Caller); return ir; } } ir = Object_Open(This, pCaller); if( ir != IR_P_RELAY ) return ir; }while(0) /* * * 名称: OBJECT_INPUT_ * 描述: 宏, Input接口的O_IX_. * 备注: 实现了V.a规则的调用O_Ix的部分. */ #define OBJECT_INPUT_ do{ IRESULT ir = Object_Input(This, IStrm, Qty, pCaller); if( ir != IR_P_RELAY ) return ir; }while(0) /* * * 名称: OBJECT_OUTPUT_ * 描述: 宏, Output接口的O_IX_. * 备注: 实现了V.a规则的调用O_Ix的部分. */ #define OBJECT_OUTPUT_ do{ IRESULT ir = Object_Output(This, OStrm, Cty, pQty, pCaller); if( ir != IR_P_RELAY ) return ir; }while(0) /* * * 名称: OBJECT_INTERACT0_ * 描述: 宏, Interact0接口的O_IX_. * 备注: 实现了V.a规则的访问IB(除NTC_ISSEND和NTC_OSSEND的交互外)和调用O_Ix的部分. */ #define OBJECT_INTERACT0_ do{ IRESULT ir; if( Act != NTC_ISSEND && Act != NTC_OSSEND ) { NUMIB i; for(i=0; i<This->NIB; i++) { ir = VVO_Interact0(*(This->ppo_AIB+i), Act, pCaller); if( (IR_P_IAEND == ir) || NIR(ir) ) return ir; } } ir = Object_Interact0(This, Act, pCaller); if( ir != IR_P_RELAY ) return ir; }while(0) /* * * 名称: OBJECT_INTERACT1_ * 描述: 宏, Interact1接口的O_IX_. * 备注: 实现了V.a规则的访问IB, 调用O_Ix的部分. */ #define OBJECT_INTERACT1_ do{ IRESULT ir; NUMIB i; for(i=0; i<This->NIB; i++) { ir = VVO_Interact1(*(This->ppo_AIB+i), Act, OStrm, Cty, pQty, pCaller); if( (IR_P_IAEND == ir) || NIR(ir) ) return ir; } ir = Object_Interact1(This, Act, OStrm, Cty, pQty, pCaller); if( ir != IR_P_RELAY ) return ir; }while(0) [/font][/td][/tr][/table] Pervise 回复于:2007-07-26 00:41:53 [table=95%][tr][td][font=FixedSys]/* * * 名称: OBJECT_INTERACT2_ * 描述: 宏, Interact2接口的O_IX_. * 备注: 实现了V.a规则的访问IB, 调用O_Ix的部分. */ #define OBJECT_INTERACT2_ do{ IRESULT ir; NUMIB i; for(i=0; i<This->NIB; i++) { ir = VVO_Interact2(*(This->ppo_AIB+i), Act, IStrm, Qty, pCaller); if( (IR_P_IAEND == ir) || NIR(ir) ) return ir; } ir = Object_Interact2(This, Act, IStrm, Qty, pCaller); if( ir != IR_P_RELAY ) return ir; }while(0) /* * * 名称: OBJECT_INTERACT3_ * 描述: 宏, Interact3接口的O_IX_. * 备注: 实现了V.a规则的访问IB, 调用O_Ix的部分. */ #define OBJECT_INTERACT3_ do{ IRESULT ir; NUMIB i; for(i=0; i<This->NIB; i++) { ir = VVO_Interact3(*(This->ppo_AIB+i), Act, IStrm, Qty, OStrm, Cty, pQty, pCaller); if( (IR_P_IAEND == ir) || NIR(ir) ) return ir; } ir = Object_Interact3(This, Act, IStrm, Qty, OStrm, Cty, pQty, pCaller); if( ir != IR_P_RELAY ) return ir; }while(0) /* * * 名称: OBJECT_CLOSE_ * 描述: 宏, Close接口的O_IX_. * 备注: 实现了V.a规则的访问IB, 调用O_Ix的部分. */ #define OBJECT_CLOSE_ do{ IRESULT ir; NUMIB i; for(i=0; i<This->NIB; i++) { ir = VVO_Close(*(This->ppo_AIB+i), pCaller); if( NIR(ir) ) return ir; } if( IR_O_NOPEN == Object_Close(This, pCaller) ) return IR_O_NOPEN; if( --This->RefCnt > 0 ) return IR_P; }while(0) /*================+ 向外声明外面直接调用的函数 +==================*/ extern FRESULT EnQueue(QUEUE* pq, BYTE* IData, BYTKTY Qty); extern FRESULT DeQueue(QUEUE* pq, BYTE* OData, BYTKTY Cty, BYTKTY* pQty); extern VOID InitAIBofND(OBJECT* pND, MLDSN* pMsn, NUMIB nib); extern VOID InitABNofND(OBJECT* pND, MLDSN* pMsn, NUMBN nbn); extern OBJECT* GetBN(OBJECT* pND, MLDSN msn); extern EM* GetEMofBN(OBJECT* pND, MLDSN msn); #endif // #ifndef __OIOIC_H__ /*============================+ 附注 +============================*/ // // OID的定义模板: // // >>> /* * * 描述: OID * 备注: OID的高48位是SID, 低16位是OSN. */ /* #define OID_SO_ 0xXXXXXXXXXXXX0000 //SO的OID起点. #define OID_PROCESS (OID_SO_ + 0) //进程(Process)的OID. #define OID_CALLER1 (OID_SO_ + 1) //Caller1的OID. #define OID_CALLER2 (OID_SO_ + 2) //Caller1的OID. #define OID_CALLER3 (OID_SO_ + 3) //Caller1的OID. ... ... ... ... #define OID_CALLERn (OID_SO_ + n) //Caller1的OID. #define OID_GO_ (OID_SO_ + n + 1) //GO的OID起点. */ // OID的定义模板 <<< // // 交互行为命名参考: // // >>> /* #define SET_YYY0 // 设置... #define GET_YYY1 // 获取... #define RCV_YYY2 // 接收... #define BGN_YYY3 // 开始... #define DSP_YYY3 // 显示... #define PRT_YYY3 // 打印... #define RDY_YYYn // 准备... */ // 交互行为命名参考 <<< // // IPF和DNG函数定义模板: // // >>> /* static IRESULT IPF_XXX() { ... } <static> VOID DNG_XXX() { ... } */ // IPF和DNG函数定义模板 <<< // // 两个典型的IPF函数示例: // // >>> /** * * 名称: IPF_Issend_Do * 描述: 数据流段输入后的处理. * 参数: This --- [IN] 指向对象本身; * pCaller --- [IN] 来访者. * 备注: NTC_ISSEND行为专用函数. */ /*static IRESULT IPF_Issend_Do(OBJECT* This, const VR* pCaller) { ... }*/ /** * * 名称: IPF_Ossend_Do * 描述: 数据流段输出后的处理. * 参数: This --- [IN] 指向对象本身; * pCaller --- [IN] 来访者. * 备注: NTC_OSSEND行为专用函数. */ /*static IRESULT IPF_Ossend_Do(OBJECT* This, const VR* pCaller) { ... }*/ // 两个典型的IPF函数示例 <<< [/font][/td][/tr][/table] Pervise 回复于:2007-07-26 00:44:21 [table=95%][tr][td][font=FixedSys]/** * * 文 件 名: OIOIC.c * * 描 述: OIOIC对象模型 .c 文件. * * 版 本: v1.0 * * 备 注: * **/ #include <stdlib.h> #include <string.h> #include "OIOIC.h" /*======================+ 各个接口的O_Ix函数 +=======================*/ /* 注意, 因为O_Ix是特殊的IPF, 函数名前没有加"IPF_"前缀, 以示与其它IPF不同. */ /** * * 名称: Object_Open * 描述: Open接口的O_Ix. * 参数: pCaller --- [IN] 来访者. */ IRESULT Object_Open(OBJECT* This, const VR* pCaller) { //IRESULT ir = IR_O; if( 0 == pCaller->cr || 0 == pCaller->mr ) return IR_N_INVALIDARG; return IR_P_RELAY; } /** * * 名称: Object_Input * 描述: Input接口的O_Ix. * 参数: IStrm --- [IN] 输入流; * Qty --- [IN] 输入的Byte数量; * pCaller --- [IN] 来访者. */ IRESULT Object_Input(OBJECT* This, BYTE* IStrm, BYTKTY Qty, const VR* pCaller) { //IRESULT ir = IR_O; if( NULLP == IStrm || 0 == Qty || 0 == pCaller->cr || 0 == pCaller->mr ) return IR_N_INVALIDARG; if( This->pq_IQ != NULLP ) EnQueue(This->pq_IQ, IStrm, Qty); return IR_P_RELAY; } /** * * 名称: Object_Output * 描述: Output接口的O_Ix. * 参数: OStrm --- [OUT] 输出流的流向; * Cty --- [IN] OStrm所指存储空间的容量; * pQty --- [OUT] 指向实际输出的Byte数量; * pCaller --- [IN] 来访者. */ IRESULT Object_Output(OBJECT* This, BYTE* OStrm, BYTKTY Cty, BYTKTY* pQty, const VR* pCaller) { //IRESULT ir = IR_O; if( NULLP == OStrm || 0 == Cty || NULLP == pQty || 0 == pCaller->cr || 0 == pCaller->mr ) return IR_N_INVALIDARG; if( This->pq_OQ != NULLP ) DeQueue(This->pq_OQ, OStrm, Cty, pQty); return IR_P_RELAY; } /** * * 名称: Object_Interact0 * 描述: Interact0接口的O_Ix. * 参数: Act --- [IN] 交互行为; * pCaller --- [IN] 来访者. */ IRESULT Object_Interact0(OBJECT* This, ACTION Act, const VR* pCaller) { IRESULT ir = IR_P; if( (ACMASK & Act) != AC0 || 0 == pCaller->cr || 0 == pCaller->mr ) return IR_N_INVALIDARG; switch( Act ) { case ASK_SHARED: //问共享么. if( !(MOD_SHARED & This->Modes) ) ir = IR_N; break; case SET_SHARED: // 设置共享。 This->Modes |= MOD_SHARED; break; case SET_UNSHARED: // 设置非共享。 This->Modes &= ~MOD_SHARED; break; case SET_BLOCKI: // 设置阻断输入。 This->Modes |= MOD_BLOCKI; break; case SET_UNBLOCKI: // 设置非阻断输入。 This->Modes &= ~MOD_BLOCKI; break; case SET_BLOCKO: // 设置阻断输出。 This->Modes |= MOD_BLOCKO; break; case SET_UNBLOCKO: // 设置非阻断输出。 This->Modes &= ~MOD_BLOCKO; break; default: ir = IR_P_RELAY; break; } return ir; } /** * * 名称: Object_Interact1 * 描述: Interact1接口的O_Ix. * 参数: Act --- [IN] 交互行为; * OStrm --- [OUT] 输出流的流向; * Cty --- [IN] OStrm所指存储空间的容量; * pQty --- [OUT] 指向实际输出的Byte数量; * pCaller --- [IN] 来访者. */ IRESULT Object_Interact1(OBJECT* This, ACTION Act, BYTE* OStrm, BYTKTY Cty, BYTKTY* pQty, const VR* pCaller) { IRESULT ir = IR_O; if( (ACMASK & Act) != AC1 || NULLP == OStrm || 0 == Cty || NULLP == pQty || 0 == pCaller->cr || 0 == pCaller->mr ) return IR_N_INVALIDARG; *pQty = 0; switch( Act ) { case GET_IQCTY: // 获取IQ容量。 if( (This->po_AND->pq_IQ != NULLP) && (Cty >= SIZEOF(BYTKTY)) ) { *((BYTKTY*)OStrm) = This->po_AND->pq_IQ->Cty; *pQty = SIZEOF(BYTKTY); ir = IR_P_IAEND; }else{ ir = IR_N; } break; case GET_OQCTY: // 获取OQ容量。 if( (This->po_AND->pq_OQ != NULLP) && (Cty >= SIZEOF(BYTKTY)) ) { *((BYTKTY*)OStrm) = This->po_AND->pq_OQ->Cty; *pQty = SIZEOF(BYTKTY); ir = IR_P_IAEND; }else{ ir = IR_N; } break; default: ir = IR_P_RELAY; break; } return ir; } /** * * 名称: Object_Interact2 * 描述: Interact2接口的O_Ix. * 参数: Act --- [IN] 交互行为; * IStrm --- [IN] 输入流; * Qty --- [IN] 输入的Byte数量; * pCaller --- [IN] 来访者. */ IRESULT Object_Interact2(OBJECT* This, ACTION Act, BYTE* IStrm, BYTKTY Qty, const VR* pCaller) { IRESULT ir = IR_O; if( (ACMASK & Act) != AC2 || NULLP == IStrm || 0 == Qty || 0 == pCaller->cr || 0 == pCaller->mr ) return IR_N_INVALIDARG; switch( Act ) { case SET_IQCTY: // 设置IQ容量。 if( (This->po_AND->pq_IQ != NULLP) && (SIZEOF(BYTKTY) == Qty) ) { free(This->po_AND->pq_IQ->Dtrm); This->po_AND->pq_IQ->Dtrm = (BYTE*)calloc(*((BYTKTY*)IStrm), 1); if( This->po_AND->pq_IQ->Dtrm != NULLP ) { This->po_AND->pq_IQ->Front = This->po_AND->pq_IQ->Rear = This->po_AND->pq_IQ->Dtrm; This->po_AND->pq_IQ->Cty = *((BYTKTY*)IStrm); This->po_AND->pq_IQ->Qty = This->po_AND->pq_IQ->Lost = 0; ir = IR_P_IAEND; }else { ir = IR_N; } }else{ ir = IR_N; } break; case SET_OQCTY: // 设置OQ容量。 if( (This->po_AND->pq_OQ != NULLP) && (SIZEOF(BYTKTY) == Qty) ) { free(This->po_AND->pq_OQ->Dtrm); This->po_AND->pq_OQ->Dtrm = (BYTE*)calloc(*((BYTKTY*)IStrm), 1); if( This->po_AND->pq_OQ->Dtrm != NULLP ) { This->po_AND->pq_OQ->Front = This->po_AND->pq_OQ->Rear = This->po_AND->pq_OQ->Dtrm; This->po_AND->pq_OQ->Cty = *((BYTKTY*)IStrm); This->po_AND->pq_OQ->Qty = This->po_AND->pq_OQ->Lost = 0; ir = IR_P_IAEND; }else { ir = IR_N; } }else{ ir = IR_N; } break; default: ir = IR_P_RELAY; break; } return ir; } /** * * 名称: Object_Interact3 * 描述: Interact3接口的O_Ix. * 参数: Act --- [IN] 交互行为; * IStrm --- [IN] 输入流; * Qty --- [IN] 输入的Byte数量; * OStrm --- [OUT] 输出流的流向; * Cty --- [IN] OStrm所指存储空间的容量; * pQty --- [OUT] 指向实际输出的Byte数量; * pCaller --- [IN] 来访者. */ IRESULT Object_Interact3(OBJECT* This, ACTION Act, BYTE* IStrm, BYTKTY Qty, BYTE* OStrm, BYTKTY Cty, BYTKTY* pQty, const VR* pCaller) { IRESULT ir = IR_P_RELAY; if( (ACMASK & Act) != AC3 || NULLP == IStrm || 0 == Qty || NULLP == OStrm || 0 == Cty || NULLP == pQty || 0 == pCaller->cr || 0 == pCaller->mr ) return IR_N_INVALIDARG; *pQty = 0; /*switch( Act ) { default: ir = IR_P_RELAY; break; }*/ return ir; } /** * * 名称: Object_Close * 描述: Close接口的O_Ix. * 参数: pCaller --- [IN] 来访者. */ IRESULT Object_Close(OBJECT* This, const VR* pCaller) { //IRESULT ir = IR_O; if( 0 == pCaller->cr || 0 == pCaller->mr ) return IR_N_INVALIDARG; if( 0 == This->RefCnt ) return IR_O_NOPEN; return IR_P_RELAY; } /*=====================+ CallerCome和CallerLeave函数 +=====================*/ /* CallerCome由VO和VVO函数专用,CallerLeave由VO函数专用, 两者外面都不能直接调用. */ /** * * 名称: CallerCome * 描述: 来访者来访, 登记来访记录. * 参数: pND --- [IN] ND地址; * pCaller --- [IN] 来访者. * 备注: 只由VO和VVO函数调用. */ FRESULT CallerCome(OBJECT* pND, const VR* pCaller) { NUMCS i; VR* pVR; /* 先监查有没有这个VR. */ for(i=0; i<pND->NCS; i++) { pVR = pND->pvr_ACS+i; if((pVR->cr == pCaller->cr) && (pVR->mr == pCaller->mr)) return FR_P_HASVR; //已经有这个VR了. } /* 加上这个VR. */ for(i=0; i<pND->NCS; i++) { pVR = pND->pvr_ACS+i; if( 0 == pVR->cr ) { *pVR = *pCaller; return FR_P; } } return FR_N; } /** * * 名称: CallerLeave * 描述: 来访者离开, 清除来访记录. * 参数: pND --- [IN] ND地址; * pCaller --- [IN] 来访者. * 备注: 只由VO函数调用. */ FRESULT CallerLeave(OBJECT* pND, const VR* pCaller) { NUMBN i; NUMCS j; VR* pVR; /* 首先ND的BN */ for(i=0; i<pND->NBN; i++) { for(j=0; j<(*(pND->ppo_ABN+i))->NCS; j++) { pVR = (*(pND->ppo_ABN+i))->pvr_ACS+j; if((pVR->cr == pCaller->cr) && (pVR->mr == pCaller->mr)) pVR->cr = pVR->mr = 0; } } /* 然后ND自己 */ for(j=0; j<pND->NCS; j++) { pVR = pND->pvr_ACS+j; if((pVR->cr == pCaller->cr) && (pVR->mr == pCaller->mr)) pVR->cr = pVR->mr = 0; } return FR_P; } /*===========================+ 入列和出列函数 +===========================*/ /** * * 名称: EnQueue * 描述: 向指定的队列入列指定数量的Byte. * 参数: IData --- [IN] 入列数据; * Qty --- [IN] 入列的Byte数量. */ FRESULT EnQueue(QUEUE* pq, BYTE* IData, BYTKTY Qty) { BYTE* newRear; //入列成功后pq->Rear应该所处的位置。 BYTKTY ctyFree, qtyEnQ; if( NULLP == pq || NULLP == IData ) { return FR_N_INVALIDARG; } ctyFree = pq->Cty - pq->Qty; qtyEnQ = (ctyFree >= Qty) ? Qty : ctyFree; if( 0 == qtyEnQ ) return FR_O_VAINLY; newRear = pq->Dtrm + (pq->Rear + qtyEnQ - pq->Dtrm ) % pq->Cty; if(newRear > pq->Rear) //如果入列成功,pq->Rear不须循环? { memcpy(pq->Rear, IData, qtyEnQ); }else //如果入列成功,pq->Rear须循环。 { BYTKTY qty1, qty2; qty1 = pq->Dtrm + pq->Cty - pq->Rear; qty2 = qtyEnQ - qty1; memcpy(pq->Rear, IData, qty1); memcpy(pq->Dtrm, IData + qty1, qty2); } pq->Rear = newRear; pq->Qty += qtyEnQ; if(ctyFree < Qty) { pq->Lost = Qty - ctyFree; // 丢失了 Qty - ctyFree 个Byte ! return FR_N_LOST; } return FR_P; } /** * * 名称: DeQueue * 描述: 从指定队列出列Byte. * 参数: OData --- [OUT] 出列数据的存储位置; * Cty --- [IN] OData所指存储空间的容量; * pQty --- [OUT] 指向实际出列的Byte数量. */ FRESULT DeQueue(QUEUE* pq, BYTE* OData, BYTKTY Cty, BYTKTY* pQty) { BYTE* newFront; //出列成功后pq->Front应该所处的位置。 BYTKTY qtyDeQ; //实际出列数据量。 if(NULLP == pq || NULLP == OData || 0 == Cty || NULLP == pQty) { return FR_N_INVALIDARG; } *pQty = 0; //先将出列数置0。 if( pq->Qty != 0 ) { qtyDeQ = (pq->Qty >= Cty) ? Cty : pq->Qty; newFront = pq->Dtrm + (pq->Front + qtyDeQ - pq->Dtrm) % pq->Cty; if(newFront > pq->Front) //出列后,pq->Front不须循环? { memcpy(OData, pq->Front, qtyDeQ); }else //出列后,pq->Front须循环。 { BYTKTY qty1, qty2; qty1 = pq->Dtrm + pq->Cty - pq->Front; qty2 = qtyDeQ - qty1; memcpy(OData, pq->Front, qty1); memcpy(OData + qty1, pq->Dtrm, qty2); } pq->Front = newFront; pq->Qty -= qtyDeQ; }else { return FR_O_VAINLY; } *pQty = qtyDeQ; if(pq->Lost > 0) { pq->Lost = 0; return FR_N_LOST; } return FR_P; } /*=============+ InitAIBofND, InitABNofND, GetBN, GetEMofBN函数 +=============*/ /* InitAIBofND, InitABNofND只由CRT函数调用. */ /** * * 名称: InitAIBofND * 描述: 初始化ND的AIB. * 参数: pND --- [IN] ND指针; * pMsn --- [IN] IB的MSN数组; * nib --- [IN] pMsn所指数组的元素个数, 即IB的数量. * 备注: 1. 只由CRT函数调用. * 2. 注意, pmn_AIB所指数组元素的排序决定了IB的访问顺序. */ VOID InitAIBofND(OBJECT* pND, MLDSN* pMsn, NUMIB nib) { NUMND i; NUMIB j; pND->NIB = nib; while(nib) { j = pND->NIB-nib; for(i=1; i<pND->NND; i++) { if( *(pMsn+j) == (pND->po_AND+i)->MSN) { *(pND->ppo_AIB+j) = pND->po_AND+i; break; } } nib--; } } /** * * 名称: InitABNofND * 描述: 初始化ND的ABN. * 参数: pND --- [IN] ND指针; * pMsn --- [IN] BN的MSN数组; * nbn --- [IN] pMsn所指数组的元素个数, 即BN的数量. * 备注: 只由CRT函数调用. */ VOID InitABNofND(OBJECT* pND, MLDSN* pMsn, NUMBN nbn) { NUMND i; NUMBN j; pND->NBN = nbn; while(nbn) { j = pND->NBN-nbn; for(i=1; i<pND->NND; i++) { if( *(pMsn+j) == (pND->po_AND+i)->MSN) { *(pND->ppo_ABN+j) = pND->po_AND+i; break; } } nbn--; } } /** * * 名称: GetBN * 描述: 获取指定的BN地址. * 参数: pND --- [IN] ND指针; * msn --- [IN] BN的M; * 返回: BN的指针. */ OBJECT* GetBN(OBJECT* pND, MLDSN msn) { NUMBN i; for(i=0; i<pND->NBN; i++) { if( msn == (*(pND->ppo_ABN+i))->MSN ) return *(pND->ppo_ABN+i); } return NULLP; //没有这个BN. } /** * * 名称: GetEMofBN * 描述: 获取指定的BN的EM地址. * 参数: pND --- [IN] ND指针; * msn --- [IN] BN的M; * 返回: EM的指针. */ EM* GetEMofBN(OBJECT* pND, MLDSN msn) { NUMBN i; for(i=0; i<pND->NBN; i++) { if( msn == (*(pND->ppo_ABN+i))->MSN ) return (*(pND->ppo_ABN+i))->pEM; } return NULLP; //没有这个EM. } /*===============================+ 附注 +================================*/ // // TOG_Xxx, CRT_Xxx, CreateObject和DestroyObject模板 : // // >>> /** * * 名称: TOG_Xxx * 描述: Xxx的TOG. */ /*<static> VOID TOG_Xxx( OBJECT* pObj ) { pObj->Open = Xxx_Open; pObj->Input = Xxx_Input; pObj->Output = Xxx_Output; pObj->Interact0 = Xxx_Interact0; pObj->Interact1 = Xxx_Interact1; pObj->Interact2 = Xxx_Interact2; pObj->Interact3 = Xxx_Interact3; pObj->Close = Xxx_Close; }*/ [/font][/td][/tr][/table] [ 本帖最后由 Pervise 于 2007-7-26 00:55 编辑 ] Pervise 回复于:2007-07-26 00:44:54 [table=95%][tr][td][font=FixedSys]/** * * 名称: CRT_Xxx * 描述: Xxx的CRT. * 参数: pOID --- [IN] OID的指针. * 返回: 对象指针, 如果创建失败返回NULLP. * 备注: === sum变量赋值模板 === * UBITS32 sum = <ND数量>*SIZEOF(OBJECT) + // for AND. * ((IQ容量大于0) ? SIZEOF(QUEUE) : 0) + //IQ的指针, 如果有IQ. * ((OQ容量大于0) ? SIZEOF(QUEUE) : 0) + //OQ的指针, 如果有OQ. * <各ND的IB数量之和>*SIZEOF(OBJECT*) + // for "ppo_AIB". * <各ND的BN数量之和>*SIZEOF(OBJECT*) + // for "ppo_ABN". * <各ND的最少CS数量之和>*SIZEOF(VR) + // for "pvr_ACS". * <各ND的EM尺寸之和, 即, SIZEOF(EM1)+...+ SIZEOF(EMn)> // for "pEM". */ /*OBJECT* CRT_Xxx( OBJID* pOID ) { UBITS32 ux_ND = ; //ND数量. UBITS32 ux_IQ = ; //IQ容量. UBITS32 ux_OQ = ; //OQ容量. UBITS32 ux_IB = ; //各ND的IB数量之和. UBITS32 ux_BN = ; //各ND的BN数量之和. UBITS32 ux_CS = ; //各ND的最少CS数量之和. UBITS32 ux_EM = SIZEOF(EM1)+...+ SIZEOF(EMn); //各ND的EM尺寸之和. UBITS32 sum = ux_ND*SIZEOF(OBJECT) + // for AND. ((ux_IQ>0) ? SIZEOF(QUEUE) : 0) + //IQ的指针, 如果有IQ. ((ux_OQ>0) ? SIZEOF(QUEUE) : 0) + //OQ的指针, 如果有OQ. ux_IB*SIZEOF(OBJECT*) + // for "ppo_AIB". ux_BN*SIZEOF(OBJECT*) + // for "ppo_ABN". ux_CS*SIZEOF(VR) + // for "pvr_ACS". ux_EM; // for "pEM". BYTE* pIC = (BYTE*)calloc(sum, 1); if( pIC != NULLP ) { OBJECT* pND; MLDSN ArrMsn[128]; BYTE* p = pIC+SIZEOF(OBJECT)*ux_ND; // // 按"LND,N1~N(ux_ND-1)"顺序确定AND各元素. // // // Xxx, 即LND, 也是N(ux_ND). pND = (OBJECT*)pIC; TOG_Xxx(pND); // 调用LND的TOG. pND->MSN = MSN_XXX; pND->OID = (*pOID)++; pND->po_AND = (OBJECT*)pIC; pND->NND = ux_ND; // // N1. TOG_Xxx1(++pND); // 调用N1的TOG. pND->MSN = MSN_XXX1; pND->OID = (*pOID)++; pND->po_AND = (OBJECT*)pIC; pND->NND = ux_ND; // // N2. TOG_Xxx2(++pND); // 调用N2的TOG. pND->MSN = MSN_XXX2; pND->OID = (*pOID)++; pND->po_AND = (OBJECT*)pIC; pND->NND = ux_ND; // // N3. TOG_Xxx3(++pND); // 调用N3的TOG. pND->MSN = MSN_XXX3; pND->OID = (*pOID)++; pND->po_AND = (OBJECT*)pIC; pND->NND = ux_ND; ... ... // // N(ux_ND-1). TOG_Xxxn-1(++pND); // 调用N(ux_ND-1)的TOG. pND->MSN = MSN_XXXn-1; pND->OID = (*pOID)++; pND->po_AND = (OBJECT*)pIC; pND->NND = ux_ND; // // 按"LND,N1~N(ux_ND-1)"顺序初始化各ND. // // // Xxx, 即LND, 也是N(ux_ND). pND = (OBJECT*)pIC; //- IQ - if( ux_IQ > 0 ) //有IQ? { pND->pq_IQ = (QUEUE*)p; pND->pq_IQ->Dtrm = (BYTE*)calloc(ux_IQ, 1); if( NULLP == pND->pq_IQ->Dtrm ) //分配IQ的容量失败? { free(pIC); return NULLP; } pND->pq_IQ->Front = pND->pq_IQ->Rear = pND->pq_IQ->Dtrm; pND->pq_IQ->Cty = ux_IQ; pND->pq_IQ->Qty = pND->pq_IQ->Lost = 0; p += SIZEOF(QUEUE); } //- OQ - if( ux_OQ > 0 ) //有OQ? { pND->pq_OQ = (QUEUE*)p; pND->pq_OQ->Dtrm = (BYTE*)calloc(ux_OQ, 1); if( NULLP == pND->pq_OQ->Dtrm ) //分配OQ的容量失败? { if( pND->pq_IQ != NULLP ) free(pND->pq_IQ->Dtrm); free(pIC); return NULLP; } pND->pq_OQ->Front = pND->pq_OQ->Rear = pND->pq_OQ->Dtrm; pND->pq_OQ->Cty = ux_OQ; pND->pq_OQ->Qty = pND->pq_OQ->Lost = 0; p += SIZEOF(QUEUE); } //- AIB, 如果有IB - pND->ppo_AIB = (OBJECT**)p; ArrMsn[0] = MSN_YYY0; ArrMsn[1] = MSN_YYY1; ArrMsn[2] = MSN_YYY2; ... ArrMsn[x-1] = MSN_YYYx-1; InitAIBofND(pND, ArrMsn, x); p += SIZEOF(OBJECT*)*x; //- ABN, 如果有BN - pND->ppo_ABN = (OBJECT**)p; ArrMsn[0] = MSN_YYY0; ArrMsn[1] = MSN_YYY1; ArrMsn[2] = MSN_YYY2; ... ArrMsn[x-1] = MSN_YYYx-1; InitABNofND(pND, ArrMsn, x); p += SIZEOF(OBJECT*)*x; //- ACS - pND->pvr_ACS = (VR*)p; pND->NCS = x; p += SIZEOF(VR)*x; //- EM - if( SIZEOF(EM_XXX) > 0 ) { pND->pEM = (EM*)p; p += SIZEOF(EM_XXX); } // // N1. ++pND; < |