7.1. Pika 对象 PikaObj

    7.1.2. 概述

    1. 对象API提供了在 C 中访问 Python 对象的一系列接口。在模块开发中使用频率最高。

    2. 对象API本身也是使用面向对象的思想设计的,这些函数的第一个入口参数都是被操作对象的指针。

    3. 一个对象由属性和方法两个部分组成,因此对象API也分为属性和方法两个部分。

    对象本身的数据类型是 PikaObj,所有 Python 对象在 C 中访问时均使用这个数据类型。

    1. /* list */
    2. Args* list;
    3. };
    4. typedef struct PikaObj_t PikaObj;

    PikaObj 内部维护了一个参数表,参数表中包含了属性信息、类信息、方法信息等。 注意不要直接访问 PikaObj 内部的参数表,请使用对象 API 访问 PikaObj。这是因为对象 API 作为对外接口,是长期稳定的,而内部实现则会随着内核代码的迭代经常变动,直接操作 PikaObj 内部将极大损失后向兼容性。

    7.1.4. 对象属性API

    这一部分 API 提供了对 Python 对象属性的访问。

    PikaObj 支持整形、浮点型、字串、指针、字节串五种基本类型的属性。使用set 和 get 方法即可读写一个对象的属性。 其中,整形,浮点型,字串和字节串和 python 中的 int, float,string,bytes 一一对应,而指针型则没有对应。

    对应关系表:

    PikaObj 的对象是动态的,因此可以随时为对象新增新的属性(静态对象的属性在构造时确定)。

    基本类型属性的 API 有如下这些:

    1. /* set API */
    2. int32_t obj_setInt(PikaObj* self, char* argPath, int64_t val);
    3. int32_t obj_setPtr(PikaObj* self, char* argPath, void* pointer);
    4. int32_t obj_setFloat(PikaObj* self, char* argPath, float value);
    5. int32_t obj_setStr(PikaObj* self, char* argPath, char* str);
    6. //create a bytes buff and copy data from 'src'
    7. int32_t obj_setBytes(PikaObj* self, char* argPath, void* src, size_t size);
    8. /* get API */
    9. void* obj_getPtr(PikaObj* self, char* argPath);
    10. float obj_getFloat(PikaObj* self, char* argPath);
    11. char* obj_getStr(PikaObj* self, char* argPath);
    12. void* obj_getBytes(PikaObj* self, char* argPath);
    13. // get size of bytes buff
    14. size_t obj_getBytesSize(PikaObj* self, char* argPath);
    15. // copy the data from bytes buff to 'out_buff', return the size of memory buff
    16. size_t obj_loadBytes(PikaObj* self, char* argPath, void* out_buff);

    基本类型属性的命名方式为 obj_set[Type] 和 obj_get[Type]。

    1. 第一个输入参数为要操作的对象指针。

    2. 第二个输入参数为属性名/属性地址。

    PikaObj 支持对象嵌套,可以访问子对象的属性,在访问子对象属性时,第二个参数为属性地址,在访问本对象的属性时,第二个值为属性名。

    1. set 方法的返回值为错误码,为 0 表示无错误发生。

    PikaObj 支持泛型属性,同样提供 set 方法和 get 方法。输入参数和返回值与基本类型相似。

    1. int32_t obj_setArg(PikaObj* self, char* argPath, Arg* arg);
    2. Arg* obj_getArg(PikaObj* self, char* argPath);

    泛型属性在使用时需要转换为基本类型。

    使用以下 API 可以判断泛型属性的当前类型。

    1. ArgType arg_getType(Arg* self);

    使用以下的 API 可以将泛型属性转换为基本类型。

    • 判断一个属性是否存在,返回值为 1 表示存在。
    1. int32_t obj_isArgExist(PikaObj* self, char* argPath);
    • 删除一个属性
    1. int32_t obj_removeArg(PikaObj* self, char* argPath);

    返回值为错误码,为 0 表示成功。

    对象方法 API 分为方法注册和方法调用两部分,方法注册部分由预编译器代理,模块开发者只需要使用方法调用 API 即可。

    7.1.6. 抛出异常

    可以在模块中使用 obj_setErrorCode 抛出异常,用户可以自定义异常处理方法(继续运行或停止运行)。 抛出异常通常在 C 模块的方法中使用,传入当前方法的 self 对象指针即可,errCode 设置为非零即可触发异常。 obj_setSysOut 方法常配合 obj_setErrorCode 方法使用,用于提供调试信息,该调试信息会在异常触发时显示在终端。

    1. /* set Error Code, if the errCode is not 0, an exaption would be throw out */
    2. void obj_setErrorCode(PikaObj* self, int32_t errCode);
    3. void obj_setSysOut(PikaObj* self, char* str);