RT-Thread 软件包-PikaScript用户手册-内核API参数表Args①
RT-Thread 软件包-PikaScript用户手册-内核API参数表Args①
9.2. 参数表 Args
RT-Thread软件包中的PikaScript用户手册针对内核API参数表Args提供了小结。Args是PikaScript引擎中的一个重要概念,用于表示传递给内核API的参数列表。
在用户手册中,针对Args的小结主要包括以下几个部分:
- Args的定义与结构:Args是一个结构体,用于存储传递给内核API的参数。Args结构体包含了一个指向参数数组的指针和参数数量,开发者可以通过设置Args结构体的成员来定义和初始化参数列表。
- Args的传递方式:Args可以通过函数调用的方式传递给内核API。开发者可以将Args对象作为参数传递给内核API函数,以便在脚本中执行特定的操作。
- Args的使用示例:用户手册中提供了一些使用Args的示例,展示了如何定义和初始化参数列表,并将其传递给内核API函数。这些示例可以帮助开发者了解Args的使用方法和应用场景。
9.2.1. 头文件
#include "dataArgs.h"
9.2.2. 概述
- Args参数表API是以 args_ 为前缀的一系列函数。
- Args参数表API是使用面向对象的思想设计的,这些函数的第一个入口参数都是被操作参数表的指针。
- Args参数表使用键值对(Map)数据模型,或称为字典(Dist)。
- 一个参数表内可以包含任意个参数,每个参数使用**参数名(键)**索引。
- 索引得到的参数可以是基本数据类型(int, float, pointer, string)或者泛型参数(Arg)。
- Args参数表支持动态地增加、删除、修改、查找参数。
- Args参数表不支持嵌套(和PikaObj属性的主要区别)。
9.2.3. 数据类型
参数表的数据类型是Args。
typedef Link Args;
参数表内部基于链表(Link)实现。
注意不要直接访问Args内部的链表,请使用Args API访问Args。以获得最大的向后兼容性。
9.2.4. 参数表的新建和销毁
- 新建参数表,从堆中新建一个参数表,返回参数表的指针。注意新建的参数表需要手动销毁来回收内存。不断新建参数表但不销毁会导致内存泄漏。
[注意] 为避免内存泄漏,请在 docker 开发环境 下进行开发,确保充足的单元测试和内存检查。
Args* New_args(Args* args);
新建参数表传入的参数是一个预留的辅助参数表,通常情况下填NULL即可。
- 销毁参数表。当一个参数表被销毁时,参数表内部的所有参数也会被自动销毁。
void args_deinit(Args* self);
传入参数表的指针,销毁参数表。
9.2.5. 增删改查API
这一部分API提供了对参数表的增删改查。
9.2.5.1. 基本类型的增删改查
Args参数表支持整形、浮点型、指针、字串四种基本类型的参数。使用set和get方法即可读写一个参数表内的参数。
Args参数表是动态的,因此可以随时为参数表新增新的参数。
基本类型属性的API有如下这些,和对象的参数API相似,但不支持嵌套:
/* set API */
int32_t args_setInt(Args* self, char* name, int64_t int64In);
int32_t args_setFloat(Args* self, char* name, float argFloat);
int32_t args_setPtr(Args* self, char* name, void* argPointer);
int32_t args_setStr(Args* self, char* name, char* strIn);
/* get API */
int64_t args_getInt(Args* self, char* name);
float args_getFloat(Args* self, char* name);
void* args_getPtr(Args* self, char* name);
char* args_getStr(Args* self, char* name);
基本类型属性的命名方式为args_set[Type]和args_get[Type]。
- 第一个输入参数为要操作的参数表指针。
- 第二个输入参数为参数名
- set方法的第三个输入参数为写入的参数值,get方法的返回值为读取的参数值。
- set方法的返回值为错误码,为0表示无错误发生。
9.2.5.2. 泛型参数
args支持泛型参数,同样提供set方法和get方法。输入参数和返回值与基本类型相似。
args_getType可以获得参数的类型。
int32_t args_setArg(Args* self, Arg* arg);
Arg* args_getArg(Args* self, char* name);
ArgType args_getType(Args* self, char* name);
泛型参数在使用时需要转换为基本类型。
使用以下API可以判断泛型参数的当前类型。
ArgType arg_getType(Arg* self);
使用以下的API可以将泛型参数转换为基本类型。
int64_t arg_getInt(Arg* self);
float arg_getFloat(Arg* self);
void* arg_getPtr(Arg* self);
char* arg_getStr(Arg* self);
9.2.5.3. 参数管理
- 使用参数名哈希或者参数名判断一个参数是否存在,返回值为1表示存在,使用times33算法获得参数名哈希。
int32_t args_isArgExist_hash(Args* self, Hash nameHash);
int32_t args_isArgExist(Args* self, char* name);
Hash hash_time33(char* str);
- 使用泛型参数的指针删除一个参数
int32_t args_removeArg(Args* self, Arg* argNow);
返回值为错误码,为0表示成功。
9.2.6. 参数表的遍历
可以使用下面的API遍历一个参数表。
- 第一个入口参数是参数表的指针。
- 第二个参数是遍历参数时的回调函数的函数指针
- 第三个参数是辅助的参数表,用来传递辅助参数,在不使用辅助参数时,第三个输入参数可以填NULL。
int32_t args_foreach(Args* self,
int32_t (*eachHandle)(Arg* argEach, Args* handleArgs),
Args* handleArgs);
9.3. 泛型参数 Arg
9.3.1. 头文件
#include "dataArg.h"
9.3.2. 概述
- arg 泛型参数API是以 arg_ 为前缀的一系列函数。
- arg 中可以保存一个任意类型的值。
- arg 支持的类型有:int,float,pointer, string, null, bytes。
- arg 放入对象后,可以直接在 python 脚本中访问 arg 的值。
9.3.3. 数据类型
泛型参数的数据类型是 Arg。
typedef struct Arg Arg;
struct Arg {
Arg* next;
uint32_t size;
uint8_t type;
Hash name_hash;
uint8_t content[];
};
泛型参数内部包括头部信息 ( size, type, name_hash ),数据体 (content),和用于构成链表的指针 (next)。
注意不要直接访问arg 内部的成员,请使用arg API访问arg 。以获得最大的向后兼容性。
9.3.4. 泛型参数的新建和销毁
- 新建泛型参数
从堆中新建一个泛型参数,返回泛型参数的指针。
注意新建的泛型参数需要手动销毁来回收内存。不断新建泛型参数但不销毁会导致内存泄漏。
[注意] 下列 api 需要内核版本不低于 v1.9.2
Arg* arg_newInt(int val);
Arg* arg_newFloat(double val);
Arg* arg_newPtr(ArgType type, void* pointer);
Arg* arg_newStr(char* val);
Arg* arg_newNull(void);
Arg* arg_newBytes(uint8_t* src, size_t size);
新建 arg 传入的参数是 arg 的值。
- 销毁泛型参数。
void arg_deinit(Arg* self);
- 复制泛型参数
Arg* arg_copy(Arg* self);
传入泛型参数的指针,销毁泛型参数。
9.3.5. 得到泛型参数的值
使用以下API可以判断泛型参数的当前类型。
ArgType arg_getType(Arg* self);
使用以下的API可以将泛型参数转换为基本类型。
int64_t arg_getInt(Arg* self);
float arg_getFloat(Arg* self);
void* arg_getPtr(Arg* self);
char* arg_getStr(Arg* self);
uint8_t* arg_getBytes(Arg* self);
size_t arg_getBytesSize(Arg* self);
9.3.6. 重要注意事项
直接使用 arg_new<Type>() api 极易引起 内存泄漏或悬垂引用,导致 致命缺陷。
请在 docker 开发环境 下进行开发,确保充足的单元测试和内存检查。
9.3.7. 案例
使用 arg 构建一个字符串列表
#include "PikaStdData_List.h"
...
/* 创建 list 对象 */
PikaObj* list = newNormalObj(New_PikaStdData_List);
/* 初始化 list */
PikaStdData_List___init__(list);
/* 用 arg_new<type> 的 api 创建 arg */
Arg* str_arg1 = arg_newStr("aaa");
/* 添加到 list 对象 */
PikaStdData_List_append(list, str_arg1);
/* 销毁 arg */
arg_deinit(str_arg1);
...
9.4. 字串池 Strs
9.4.1. 头文件
#include "dataStrs.h"
9.4.2. 概述
- Strs字串池API是以 strs 为前缀的一系列函数。
- 字串池为字符串提供提供动态的内存空间,支持任意长度的字符串,一个字串池能够存储任意多个字符串。
- 提供方便的内存管理,在销毁字串池时,池内的所有字符串内存会被自动批量销毁。
- 提供安全的操作方式,在使用strs API时,被引用的字符串不会被修改。所有修改在新申请的内存区产生。因此不会出现悬空指针,被引用的字符串被篡改之类的严重安全问题。
- Strs字串池API是使用面向对象的思想设计的,这些函数的第一个入口参数都是被操作字串池的指针。
9.4.3. 数据类型
Strs的数据类型是Args,内部维护一个参数表。
typedef Link Args;
注意不要直接访问字串池的参数表,请使用Strs API访问Strs,以获得内存安全性和最大的向后兼容性。