配置文件格式:关键字 等号 代码说明(不含等号作为注释行)。 ^关键字:表示系统参数,请勿修改。 @代码说明:声明一个代码模板。在输入时自动删除模板中以 //开始的注释行 .代码说明: 表示命名空间重定向。 关键字中.为命名空间分隔符。或者将.前面的标点解析为命名空间分隔符,例如::.全局常量成员, functionname(.(参数一,参数二)表示函数的形参说明。 使用__指示光标插入位置 ------------------------------------------ ^MAXTIER = 36 ^IGNORECASE_NODE_KEY = 1 _AARDIO_VERSION = aardio 内核版本号 _HAPPICON = 应用程序图标句柄,可在工程属性中自定义该图标,\n图标在不再使用时会自动释放,不要手动释放该图标\n_HAPPICON仅在启动线程中存在 _STUDIO_INVOKED = 检测程序是否在 aardio 开发环境内运行。\n\n可能的值如下:\n\n- 值为 "process": aardio 程序是在开发环境内以独立的进程模式运行。\n\n- 值为 "thread": aardio 程序是在开发环境主进程内以线程模式运行。\n\n└── 在开发环境内启动并且首个 import 语句导入的是 ide 库即以线程模式运行。\n\n└── 为保持开发环境的稳定与独立性,任何时候都不建议使用线程模式。\n\n- 值为 "external": 外部程序在非主线程内将开发环境设为应用根目录,并且导入了 ide 库。\n\n└── 此模式可启用自动安装扩展库等功能。\n\n- 值为 null : 表明 aardio 程序不是由开发环境启动,并且未在非主线程导入 ide 库。 _IMPORTURL = 用于注册远程扩展库安装网址的表,\n可添加新的键值,键为库名称,值为库安装文件网址,\n网址可指定 *.tar.lzma 格式安装包或 *.aardio 格式库文件"\n必须写在引用扩展库的语句之前 _IMPORTURL.? = 键为库名称值为远程库网址,\n网址可指定 *.tar.lzma 格式安装包或 *.aardio 格式库文件,\n\n例如:\n"https://github.com/.../releases/latest/download/yourlibname.tar.lzma"\n必须写在引用扩展库的语句之前 _WINE = 如果程序在 Linux(Wine、CrossOver) 环境下运行此常量包含wine版本号\n否则为 null _WINXP = 当前系统是否为WINXP或Win2003\n否则为Vista/WIN2008或以后的版本 _WIN7_LATER = 当前系统是否为WIN7/Win2008 R2或之后的版本 _WIN10_LATER = 当前系统是否为WIN10/Win2016或之后的版本 _WIN_64 = _WIN_64 = 当前系统是否为64位 _WIN_VER_MAJOR = Windows 主版本号 _WIN_VER_MINOR = Windows 副版本号 _WIN_VER_BUILD = Windows 构建版本号\nWindows10 构建版本号与发行版本号的对应关系请参考 win.versionEx _CMDLINE = 命令行参数的原始文本\n也可以使用 _ARGV 获取解析后的命令行参数\n_CMDLINE 仅在启动线程中存在,一般用于main.aardio,开发环境中为null\n可使用#操作符检测参数是否为空 _ARGV = 解析后的进程启动参数表,已解析双引号、命令行参数转义符等并转换为数组,\n命令行解析规则请参考标准库中 string.cmdline 的源码,\n\nARGV 既包含命令行参数数组,也包含按下列规则解析的键值对:\n以斜杠或短横线开始的前导参数作为键(键名移除一个或多个相同的前导字符,区分大小写),\n如果前导参数包含等号,则以等号拆分为键值对,等号前后不应有空格,\n否则检查下一参数如果没有相同的首字符则设为此键对应的值,\n如果一个前导参数没有指定值,则默认值为空字符串(逻辑值为true)\n\n_ARGV仅在发布后的进程启动线程中存在,开发环境中 _ARGV 为空表。\n非主线程请改用 thread.cmdline _ARGV.? = 请输入命令行参数中以斜杠或短横线开始的前导参数名。\n注意参数名区分大小写 _MAX_PATH_U8 = @0x410/*_MAX_PATH_U8*/ _MAX_PATH_U16 = @0x208/*_MAX_PATH_U16*/ intellisense代码模式 = @/*intellisense(__/*请输入命名空间*/)*/\n\n/*end intellisense*/\n intellisense注释模式 = @/*****intellisense(__/*请输入命名空间*/)\n\nend intellisense*****/\n this = 在类定义内部指向当前创建的类实例对象,\n不可作为参数传入其他线程。 owner = 默认指向拥有当前成员函数的所有者对象,\n使用 对象.成员函数(参数) 格式调用成员函数时,\n函数名前面的对象即成员函数的 owner 参数。\n使用[]或[[]]操作符调用成员函数时 owner 参数为 null。\n\n在迭代器函数中的 owner 表示遍历的集合对象,\n在对象的元方法中,owner 表示当前对象或左操作数。\n导入库时库文件的 owner 参数为库文件路径或内存数据(发布后的嵌入库)。\n独立运行 aardio 文件时 owner 参数为 null。 global = 全局命名空间\nglobal.x 等价于 ..x\n. self = 当前命名空间 rget(.(startIndex,->->->) = 自参数 @1 指定截取后续参数列表的起始位置,可使用负数表示尾部倒计数。\n可以使用返回多个值的函数调用语句指定其他参数。 rget(.(array) = 展开并返回参数 @1 指定的表对象包含的所有数组成员。 rget(.(func,->->->) = 将后续参数作为调用参数调用参数 @func 指定的函数,并返回被调用函数的全部返回值。 loadcode(__) = 编译aardio代码并返回函数对象,失败返回null以及错误信息,\n参数可以是aardio文件,或者aardio代码,或者指定的loader函数\n可选使用参数@2自定义代码块名称\n\n注意使用相对路径时的参考目录必须是应用程序根目录,并以斜杠作为路径首字符\n参数不应使用参考当前目录的路径,因为当前目录是可变的,\n可自工程中拖动文件到代码中生成正确路径 loadcodex( = 加载并运行aardio文件或代码\n注意使用相对路径时的参考目录必须是应用程序根目录,并以斜杠作为路径首字符\n参数不应使用参考当前目录的路径,因为当前目录是可变的,\n可自工程中拖动文件到代码中生成正确路径 loadcodex(.(函数,->->->) = 运行函数,可指定多个调用参数\n返回值为被调用函数的返回值 loadcodex(.(aardio代码,->->->) = 加载并运行aardio文件或代码,可指定多个调用参数,\n被调用文件可在开始处使用 ... 操作接收多个参数\n返回值为被调用文件的返回值 dumpcode(__) = 将函数输出为字节码,\n参数一可以是aardio代码,aardio源文件路径,或函数对象,\n可选用参数@2自定义代码块名称\n可选用参数@3指定是否移除调试信息 assert(__) = 断言函数\n第一个参数为真则返回此参数\n否则将第二个参数作为异常抛出 assertf(__) = 反断言函数\n第一个参数为假则返回第二个参数)\n否则将第二个参数作为异常抛出 error( = 抛出一个异常。\n\n如果库函数报错,也可以临时增加代码检查异常参数,\n并使用 error 函数向指定的调用级别抛出异常,以辅助定位错误的调用代码\n\n禁止在 catch 语句内部调用 error 函数( global.onError 更方便 )\n\n如果发布程序禁用调试信息则 error 输出的信息会被精简。\n而 errput 输出的错误信息会被保留(调用栈信息仍会被精简) error(.(错误信息,调用级别) = 抛出一个异常。\n\n可选用参数 @2 指定抛出异常的调用级别,\n1 为自身,2 为上层调用者,依次上推……\n\n如果库函数报错,也可以临时增加代码检查异常参数,\n并使用 error 函数向指定的调用级别抛出异常,以辅助定位错误的调用代码 errput( = 输出错误信息,但不会抛出异常。 errput(.(错误信息,错误标题) = 输出错误信息。\n如果参数@1为空则忽略不执行任何操作,参数 @2 可省略。\n此函数会首先触发默认错误处理程序,\n如果错误处理程序或 onError 返回 null 则不输出错误信息。\n\nerror 函数会中断执行并抛出异常,直到异常被捕获。\nerrput 则不会抛出异常,错误信息输出以后程序会继续向后执行。\n\n如果发布程序禁用调试信息则 error 输出的信息会被精简。\n而 errput 输出的错误信息会被保留(调用栈信息仍会被精简) lasterr(.(err) = 返回WINAPI或COM API的最后一次错误信息,第二个返回值为错误码\n无错误则返回null空值,\n可选使用参数 @err 自定义错误代码 call(.(函数,owner,其他调用参数->->->) = 调用函数,可自定义owner对象,\n参数@1可以是类、函数等可调用的对象,\n即使是不可调用类型或者null值也不会抛出异常,\n可以有任意个其他调用参数\n\n成功首个返回值true,其他返回值为被调用函数返回值,\n失败返回 false,错误信息 callex(.(错误处理函数,调用函数,owner,其他参数) = 调用函数,可自定义owner对象,\n不指定错误处理函数时调用默认错误处理函数,可触发global.onError,\n返回值一表示调用是否成功,其他返回值为函数返回值\n失败返回false,错误信息 invoke(.(调用函数,owner,其他调用参数->->->) = 调用函数,可自定义被调用函数的owner参数,\n返回值为函数返回值,失败则直接抛出异常\n可添加任意个数的调用参数\n\n这个函数的参数用法与 call 函数完全相同,\n但 invoke 只有修改 owner 的作用,不会捕获异常,\n也不会改变函数的返回值 eval("__") = 将字符串转换为代码执行,并返回一个或多个值\n失败抛出异常\n注意,如果是开发网站或服务端,\n应避免用户提交的字符串可以在eval中执行,\n服务端到客户端传输数据时不应使用eval实现序列化\n因为eval可以执行任意的代码\n服务端到客户端间序列化数据,应当改用普通的数据解析器,例如json execute("__") = 调用系统命令行,成功返回 0,此函数会打开命令行窗口。\n以下库或函数提供类似且更强大的功能:\nraw.execute,\nprocess,\nprocess.execute,\nprocess.popen,\nprocess.popen.cmd 专用于启动命令行,\nprocess.popen.cmd64 专用于启动 64 位命令行,\nprocess.popen.ps,\nprocess.wow64.execute 专用于启动 64 位程序,\nconsole.pause reduce(数组,回调函数,初始值) = @reduce(__/*从左到右遍历数组中的值并应用回调函数归约运算为单个值。\nprev 参数数为上次调用返回的值或初始值。\n无初始值则取首个成员值为初始值,并自第2个成员开始遍历。\nnext 参数为下一个成员值,index 参数为下一个成员索引。\narr 参数为正在遍历的数组,arr 与 owner 参数指向同一对象。*/,function(prev,next,index,arr){\n return prev + next\n}) import = @import __/*导入库到当前命名空间,同时导入库到全局命名空间,\n不会使用库命名空间下的变量污染当前命名空间。\n\n访问导入库的成员必须写完整的命名空间路径,\n导入命名空间以前,该命名空间应当为null,或是已导入的相同库,\n如果是其他值,例如数值则会报错,import 语句不会触法表的元方法,\n\n可以重复调用import语句导入相同的库,\n但一个库在一个线程中只会被真正导入一次,\n如果一个库已经被导入过,aardio会直接自global命名空间获取,\n不应在global命名空间删除导入的库,或使用冲突的全局名称. \n\n如果希望动态加载一个库,却不希望添加到发布程序中,\n或者库名字是一个变量,可以使用global.import("命名空间")导入库*/ type.eq(__, ) = 比较两个对象的数据类型、元类型、结构体类型是否完全相同,\n如果一个函数的返回值用于逻辑判断,此类函数返回布尔值(true,false),\n在aardio 一个说明返回布尔值的函数,实际允许返回任意类型的值,\n如果此类函数无返回值,应视为返回 null值,\n如果此类函数返回 null 值,应视为 false 值,\n具体请参考 aardio 基础语法文档中的说明,\naardio支持宽松的类型转换,在其他类似函数中不再做额外说明 type.rget(__) = 调用type函数检测对象类型\n并返回最后一个类型描述\ntype 函数检测一个对象时,可能返回一个或多个类型描述,\n分别为数据类型、元类型、结构体类型 type.null = 空值:基本数据类型 type.pointer = 指针值:基本数据类型 type.boolean = 布尔值:基本数据类型 type.string = 字符串:基本数据类型 type.number = 数值:基本数据类型 type.table = 表:基本数据类型 type.buffer = 缓冲区:基本数据类型。\n由 raw.buffer 函数分配的可读写、固定长度的内存,\n可用于存取可读写的二进制字节串(Byte String),在几乎所有字符串函数中都可以作为字符串使用。 type.cdata = 内核对象:基本数据类型 type.fiber = 纤程:基本数据类型 type.function = 函数:基本数据类型 type.class = 类:基本数据类型 type.file = 元类型名"io.file"。\n使用 io.file 打开的文件以及标准输入输出对象的元类型。 type.isString(__) = 参数 @1 如果是 string 或 buffer 类型返回 true type.isFile(__) = 参数 @1 如果是 io.file,fsys.file,fsys.stream 对象则返回 true。 type.callable(__) = 判断参数是否函数、类、或其他可调用对象 type = 对象类型检测 type( = 类型检测函数 type(.(__需要返回数据类型的变量) = 检测数据类型,返回值1为基本数据类型\n如果返回两个或三个值,最后的返回值为元表中_type的值,\n结构体返回三个值,第二个返回值为结构体声明 tostring( = 转换参数@1指定的值为字符串类型,不修改输入参数, tostring(.(number,radix,decPoint) = 转换 @number 指定的数值为字符串。\n可选用参数@2指定进制,指定16进制添加0x前缀,其他进制无前缀。\n\n参数 @decPoint 可选用表示字节码的数值指定小数点,\n不指定则使用当前区域默认小数点:\n汉语和多数英语环境使用句点,多数欧洲国家使用逗号。\n可调用 setlocale("numeric") 修改区域以改变默认小数点 tostring(.(time,format,locale) = 转换 @time 指定的时间对象为字符串。\n可选用 @format 自定义时间格式化串,参数 time 对象文档,\n可选用 @locale 指定格式化区域,用法与 setlocale 参数@2相同,\n例如简体中文为 "chs" 英语为 "enu" tostring(.(value,->->->) = 转换参数@1指定的值为字符串类型,不修改输入参数。\n\n如果对象指定了 _tostring 元方法则调用该元方法返回值,\ntostring 第二个参数开始会传递为 _tostring 元方法的参数 tonumber( = 转换参数并返回数值,不修改输入参数,失败返回 null\n转换成功会返回多个值,将返回值放入圆括号可转换为单个值。\n\n在数值运算,以及 math 函数库除有特别说明以外都支持字符串参数自动转数值。\n其他函数的数值参数如用于上述数值运算,同样支持字符串自动转数值。\n原生 API 函数,COM 函数则应当明确区分字符串与数值 tonumber(.(值) = 转换参数并返回数值,\n如果参数@1是指针类型变量转换为内存地址,\n如果参数@1是布尔值,false转为0,true转为1\n如果参数是字符串或buffer类型,转换成功返回数值以及转换的字符串长度,\n其他对象尝试调用_tonumber元方法转换为数值\n转换失败返回null tonumber(.(字符串,进制,开始位置,默认小数点) = 强制转换字符串为数值类型,自动识别进制,\n忽略首尾空白字符,空白字符串返回 null,\n注意空白字符串在算式或等式中会自动转换为 0 而不是 null,\n\n参数@1可以是字符串或buffer类型,\n可选用参数@2指定进制,可选用参数@3指定开始位置\n参数@4可选用表示字节码的数值自定义小数点,\n不指定使用当前区域默认小数点:\n汉语和多数英语环境小数点默认为句点,多数欧洲国家小数点默认为逗号,\n可调用 setlocale("numeric") 修改默认区域,\n请注意:即使指定了小数点,区域默认小数点仍然是有效的。\n\n转换成功返回数值,以及转换为数值的字符串长度\n转换失败返回null topointer( = 转换参数并返回指针,不修改输入参数。\n\n相关函数: raw.toPointer topointer(.(内存地址) = 转换数值参数并返回指针,不修改输入参数。\n参数 @1 为 0 或 null 时返回 null,忽略其他参数。\ntopointer(0) 是多余无意义的写法,请直接写 null 。\n\n此函数仅作类型转换,不能提取对象内部指针\n提取指针应使用raw.toPointer函数 topointer(.(指针,偏移值) = 指针必须是 pointer 类型指针, 参数@1 为 null 时返回 null 。\n偏移值以字节为单位,可以为负数。\n\n此函数仅作类型转换,不能提取对象内部指针。\n提取指针应使用 raw.toPointer函数 sleep(__/*毫秒*/) = 延时(CPU 休眠.)\n此函数返回值总是为 true。\n提升 sleep 函数计时精度请使用 time.period 或改用 time.performance.delay。\n\nsleep 函数会卡界面并影响其他依赖消息处理的功能。\n界面线程请改用 thread.delay 函数。\n界面线程请改用 thread.delay 函数。\n界面线程请改用 thread.delay 函数。 setlocale(."all") = 返回当前区域设置 setlocale(."all","__") = 修改当前区域设置为默认设置\n返回区域设置全称 setlocale(."all","chs") = 简体中文语言区域设置\n返回区域设置全称 setlocale(."all","enu") = 英文语言区域设置\n返回区域设置全称 setlocale(."collate","__") = 设置 string.collate 函数比较文本时使用的本地化区域,\n返回区域设置全称,仅获取设置可省略参数 @2 setlocale(."ctype","__" ) = 设置当前程序字符类别及转换使用的本地化区域,\n返回区域设置全称,仅获取设置可省略参数 @2 setlocale(."monetary","__" ) = 设置当前程序金融货币使用的本地化区域,\n返回区域设置全称,仅获取设置可省略参数 @2 setlocale(."numeric","__" ) = 设置当前程序使用的数值本地化区域,影响默认小数点,\n主要影响的是 tonumber 与 tostring 等数值与文本转换函数,\n不会影响 aardio 语法解析中的小数点(总是句点)。\n\n汉语和多数英语环境小数点默认为句点,多数欧洲国家小数点默认为逗号,\n返回区域设置全称,仅获取设置可省略参数 @2 setlocale(."time","__" ) = 设置当前程序时间日期格式使用的本地化区域,\n返回区域设置全称,仅获取设置可省略参数 @2 setlocale(."time","chs") = 设置时间日期格式使用简体中文语言区域区域,\n返回区域设置全称,仅获取设置可省略参数 @2 setlocale(."time","enu") = 设置时间日期格式使用英文语言区域,\n返回区域设置全称 setprivilege('SeDebugPrivilege',true) = 设置指定进程权限\n成功返回true,失败返回false and = 逻辑与运算符 not = 逻辑非运算符 or = 逻辑或运算符 true = 逻辑值:真(true,所有非null、非零值) false = 逻辑值:假(false,null、零) null = 空值 with= @with __/*请指定要设为当前命名空间的表达式。\nwith语句将对象临时绑定到当前命名空间,执行结束释放绑定。\n命名空间作用域为当前函数体(以及内部函数),单个代码文件属于匿名函数。\nwith 语句必须执行完成(没有中途跳出)才能恢复当前函数命名空间。*/{\n //在名空空间内应使用 .. 操作符访问外部全局命名空间下面的对象\n \n}\n namespace = @namespace __/*指定命名空间路径,打开存在的命名空间或创建新命名空间。\nnamespace 语句不会触发命名空间的元方法(with 语句则相反)。\n注意 .NET 命名空间依赖元方法自动导入下级命名空间。\n\n命名空间作用域为当前函数体(以及内部函数),单个代码文件属于匿名函数。\nnamespace 语句块必须执行完成(没有中途跳出)才能恢复原命名空间。\n如果当前文件不需要恢复命名空间,可省略后面的语句块。*/{\n //在名空空间内应使用 .. 操作符访问外部全局命名空间下面的对象\n \n}\n begin = @begin\n __/*语句块限定局部变量作用域*/\n\nend;\n end = @end;//表示语句块结束 function = @function(__/*请输入函数形参*/){\n \n}\n class = @class {\n ctor(){\n this.property = "";\n }; \n method = function(){ \n return this.property;\n };__/*类构造器内所有成员必须用分号分隔*/\n}\n lambdaλ = @λ (__/*lambda定义一个匿名函数,\n用于接收输入参数并返回一个表达式,\n不能使用表达式以外的其他语句或语句块,\n不能返回多个值*/) lambda = @lambda (__/*lambda定义一个匿名函数,\n用于接收输入参数并返回一个表达式,\n不能使用表达式以外的其他语句或语句块,\n不能返回多个值*/) if = @if(__/*条件判断*/){\n \n} else = @else{\n__\n}\n elseif = @elseif(__){//否则判断条件\n\n\n}\n select = @select(__/*匹配这里指定的值,执行首个匹配的分支语句然后退出。\n不会向下穿透继续执行其他 case 分支,全部匹配失败则执行 else 分支语句。\ncase 指定单个值默认使用恒等运算符比对(不转换类型),可在前面自定义运算符。\ncase 指定逗号分隔的多个值则匹配其中一个成功即可,可在前自定义运算符。\ncase 使用分号分隔两个数值时指定数值范围,只能使用 `>=`与`<=` 运算符匹配。\n使用 switch 函数可利用表对象查询实现更简单更快的索引匹配并执行分支函数。*/){\n case 2 {\n }\n case 1,9,10 {\n }\n case 10;20 {\n }\n case !=0 {\n }\n else {\n }\n} switch(selector,caseTable,default,->->->) = @switch(__/*参数 @selector 可指定任意索引值。 \n@caseTable 参数必须指定一个待检索的表对象(不能是其他数据类型)。 \n@default 参数可省略或指定一个代替 @caseTable.default 的函数对象。 \n\n使用 @selector 作为索引获取 @caseTable 表对应的成员函数并执行, \n如果没有找到函数则执行 @default 或 caseTable.default 指定的默认函数。 \n如果没有匹配到任何函数或默认函数则忽略不执行任何操作。 \n\n@default 参数后面的所有参数依序转发给被调用函数。 \n调用的所有返回值由 switch 函数原序转发给调用方。*/,{ \n case1: function(){\n \n };\n case2: function(){\n \n }; \n case3: function(){\n \n }; \n default: function(){\n \n }; \n}) while = @while(__/*请在这里输入循环条件*/){//如果条件符合,则循环执行下面的代码\n\n\n}\n while_var = @while(var i = __/*每次循环前运行此赋值语句直到循环变量为非真值*/){\n \n} do = @do{\n \n __/*先执行再判断 while 条件是否继续循环。*/\n \n} while(0); for = @for(i=1;__;1){\n \n\n}\n for_in = @for(k,v in __/*\n指定函数对象则作为迭代器循环调用直到返回 null 。\n指定函数调用语句则必须返回函数对象(作为循环执行的迭代器)。\n指定表对象(或数组)则遍历该表返回表示键值的循环变量 k,v 。\n如果在这里指定表:\n- 在迭代中只能修改表的键值,不可增加新键(可能打乱迭代次序)\n- 迭代表对象的非数组成员时不保证遍历顺序。\n- 排序遍历表中的名值对请调用 table.eachValue 创建迭代器。\n- 顺序遍历数组或伪数组可调用 table.eachIndex 创建迭代器。\n- 改用计数 for 循环遍历数组则能保持索引顺序。*/){\n \n\n} try_catch = @try{\n __/*注意只有 return 语句可以退出 try 或 catch 语句。\n不能访问此语句外部的 ... 参数,可提前用 {...} 转换为数组。*/\n}\ncatch (e){\n \n} try = @try{\n __/*注意只有 return 语句可以退出 try 语句。\n不能访问此语句外部的 ... 参数,可提前用 {...} 转换为数组。*/\n}\n var = @var __/*要定义的局部变量名*/ = ; //局部变量作用仅限于当前语句块内部 return = @return __; //返回一个或多个值,多个值请使用逗号分开 break = 中断循环,\n可选指定中断的循环标号,\n标号在循环语句块开始指定并紧跟一个冒号,\n也可以指定要中断的循环嵌套层数,\n本层循环为1,上层循环为2,向上依次累加 continue = 跳过本次循环,\n可选指定跳过的循环标号,\n标号在循环语句块开始指定并紧跟一个冒号,\n也可以指定要跳过的循环嵌套层数,\n本层循环为1,上层循环为2,向上依次累加 collectgarbage(."stop") = 禁用垃圾收集器 collectgarbage(."restart") = 重启垃圾收集器 collectgarbage(."count") = 查询内存占用(Kb) collectgarbage(."setpause") = 垃圾收集暂停时间值\n第二参数除以100代表内存回收前要等多久,\n默认值为200,指定内存达到上一个周期结束时的两倍时进入下一个周期,\n函数返回原来的设置值 collectgarbage(."setstepmul") = 设置垃圾收集器步长倍增器的值\n第二参数除以100代表单步的速度,\n默认值为200,也即内存分配速度的两倍\n函数返回原来的设置值 collectgarbage(."collect") = 运行完整的垃圾回收 collectgarbage(."step",1) = 进行一次垃圾回收迭代,\n参数2越大,执行的次数越多,执行时间越久,\n如果已经是最后一次迭代返回true table = 表、数组函数库\n这是自动导入的内置库,\n[使用手册相关文档](doc://library-guide/builtin/table/_.md) table.unique(__) = 对参数 @1 指定的数组去重\n返回去重后的新数组\n不修改原来的数组 table.next(.(tab) = 获取 @tab 参数指定的表对象的第一个键值对元素 table.next(.(tab,key) = 获取 @tab 参数指定的表对象的下一个键值对元素 _serialize = @_serialize = function(kernelCall){\n return __/*返回序列化字符串。\n使用 table.tostring 序列化表对象时会调用此元方法,\naardio 内核在通过序列化的方式复制表对象时也会隐式调用此元方法。\n内核隐式调用此元方法时 kernelCall 参数为 true 。*/;\n} table.tostring( = 序列化表对象并返回字符串 - 包含构建该表的 aardio 代码。\n返回字符串可传入 eval 函数并返回新的表对象。\n\n仅序列化以字符串、数值为键的元素,\n仅序列化值为字符串、数值、buffer 以及定义了 _serialize 元方法的成员。\n循环引用的值转换为 null,序列化时忽略成员函数 table.tostring(.(tab) = 序列化参数 @1 指定的表对象,\n返回纯文本格式的字符串 - 包含构建该表的 aardio 代码。\n支持使用 _serialize 元方法自定义序列化操作 table.tostring(.(tab,true) = 序列化参数 @1 指定的表对象。\n支持使用 _serialize 元方法自定义序列化操作。\n\n返回的代码包含二进制格式,不可直接编辑,\n返回的字符串仍然可以可以使用 eval 函数重新解析为 aardio 对象,\n但体积更小,解析速度更快 table.concat( = 连接数组并且混入其他键值到一个新的数组,支持多参数,返回新数组\n此函数不会修改参数传入的表,而是返回一个新的表,\n\n如果要连接数组并修改参数@1传入的数组,\n请改用 table.append 函数 table.concat(.(->->->) = 连接任意个数表参数并返回新的表,\n即使不传入任何参数也会返回一个新表,\n数组并且混入其他键值到一个新的表,支持多参数,返回新的表,\n连接时下一个数组的开始索引总是在前面所有数组的数组成员总数加一\n拼接的数组不应包含不连续数值索引的稀疏数组\n此函数复制元素使用浅拷贝,只读成员冲突会导致异常 table.append( = 连接一个或多个数组到参数@1指定的数组,返回该数组,\n此函数不会创建新的数组,复制元素使用浅拷贝,\n如果希望连接数组并返回新数组而不修改传入参数应改用 table.concat 函数 table.append(.(->->->) = 连接一个或多个数组到参数@1指定的数组,支持多参数,返回参数@1\n自第二个参数开始为可选参数,所有null自动忽略。\n连接时下一个数组的开始索引总是在前面所有数组的数组成员总数加一\n拼接的数组仅限于有序连续数值索引的数组成员 table.insert(.(数组,要插入的值,要插入的位置 ) = 插入元素到数组指定位置,\n可使用负数表示右侧反向计数 table.insert(.(数组,要插入的值 ) = 插入元素到数组头部 table.remove( = 在表中指定位置移除元素,返回移除的元素 table.remove(.(array,移除位置 ) = 在@array 参数指定的数组指定的移除位置为移除元素,\n移除位置省略时则默认值为1,\n可使用负数表示右侧反向计数,\n返回值为移除的元素 table.remove(.(array ) = 在@array 参数指定的数组头部移除元素 table.push(.(array,__) = 在 @array 参数指定的数组尾尾部压入一个或多个元素,返回数组大小 table.push(.(array,__v1,v2,v3,...) = 在 @array 参数指定的数组尾尾部压入多个元素,返回数组大小 table.pop( = 在数组尾部弹出一个或多个元素并作为返回值\n此函数会修改参数 @1 指定的数组以移除弹出的元素 table.pop(.(array,length) = 在 @array 参数指定的数组尾部弹出 @length 参数指定个数的元素并作为返回值\n省略 @length 参数则默认弹出一个元素,\n如果 @length 为负数,弹出元素从后向前反向排列\n空数组不返回任何元素 table.unshift(.(数组,要插入的一个或多个元素) = 插入一个或多个元素到数组头部,返回数组长度\n插入多个参数时会保持参数时传入的顺序不变 table.shift( = 自数组头部移除指定个数的元素 table.shift(.(数组,移除数目) = 自数组头部移除指定个数的元素,\n并返回这些移除的元素,每个返回值返回一个移除元素。\n参数 @2 可选,默认为 1 table.splice(.(数组,位置,删除长度,要插入的一个或多个元素) = 在数组指定位置删除指定长度元素,替换为不定个数的插入元素,\n如果删除了元素,该函数返回包含删除元素的数组 table.sort( = 排序数组 table.sort(.(array) = 排序 @array 参数指定的数组,函数无返回值。\n默认将较小的值排序在前。 table.sort(.(array,compareProc) = @.sort(__/*排序 @array 参数指定的数组,函数无返回值。\ncompareProc 指定用于比较元素大小的函数。\n该函数比较 owner 参数与第一个参数,owner 排序在前面则返回 true。\n\n注意数值使用 `<` 或 `>` 比较,\n2 个值相等不应当返回 true,不应直接用 `<=` 或 `>=` , `==` 判断并返回值。*/,lambda(next) owner > next ) table.reverse(__) = table数组倒序排列,\n注意此函数无返回值 table.range( = 如果指定 table 对象作为参数,\n则用于获取 table 对象的最小数值索,最大数值索引。\n指定数值参数则可用于生成序列数组。 table.range(.(tab) = 返回 table 对象的最小数值索引,最大数值索引。\n通常用于获取稀疏数组的数值索引范围。\n\n改用 `#` 操作符则仅获取稠密数组长度。\n改用 table.len 函数则可获取数组或类数组长度。\n改用 table.count 函数则可以获取表中所有成员(数组或非数组成员)的总数。 table.range(.(start,stop,step,map) = 返回一个序列数组,此数组可同时作为 for in 语句的迭代器使用\n以 step 为步进生成包含从 start 到 stop 数值的数组(包含 stop)。\n可选指定 map 函数用于接收生成的数值并转换为新的值。 table.range(.(start,stop,map) = 返回一个序列数组,此数组可同时作为 for in 语句的迭代器使用。\n以 1 为步进生成包含从 start 到 stop 数值的数组(包含 stop)。\n可选指定 map 函数用于接收生成的数值并转换为新的值。 table.range(.(stop,map) = 返回一个序列数组,此数组可同时作为 for in 语句的迭代器使用。\n以 1 为步进生成包含从 1 到 stop 数值的数组(包含 stop)。\n可选指定 map 函数用于接收生成的数值并转换为新的值。 table.unpack(.(array,i,j) = 返回 @array 参数指定的数组中自i到j的元素。\n可用负数表示倒计数,-1 表示最后一个元素。\n省略 i 则 i 为 1,省略 j 则 j 为 -1。\n省略 i,j 参数则返回数组中的所有元素。\n如果i,j都不小于零,则不检测数组长度,不存在的元素在对应位置返回 null 值 table.left(.(array,len) = 返回 @array 参数指定的数组左侧开始返回指定个数的元素。\n此函数不是返回包含指数目元素的数组,而是多一个元素多一个返回值。\n如果要返回数组请改用 table.slice 函数 table.right(.(array,len) = 返回 @array 参数指定的数组右侧开始返回指定个数的元素。\n此函数不是返回包含指数目元素的数组,而是多一个元素多一个返回值。\n如果要返回数组请改用 table.slice 函数 table.clone(__) = 返回一个克隆后的新table对象,保持元表不变。\n使用深拷贝,( 混入函数 table.assign 使用浅拷贝复制表 ).\n而 table.create 使用写时拷贝复制表 table.count(__) = 获取表对象( table )包含的成员总数,\n返回数目为包含稠密数组成员与其他键值对的总数。\n\n如果使用 `#` 操作符取数组长度仅计算稠密数组成员的总数。\n使用 table.len 函数则可以获取纯数组、类数组、伪数组的长度。\n使用 table.range 函数可以获取稀疏数组的最小与最大索引。 string = string字符串函数库 string.unhex( = 还原使用 16 进制编码的字符串。 string.unhex(.("16进制编码数据","前缀") = 还原使用 16 进制编码的字符串,解码失败返回 null 值\n前缀可包含一个或多个字符,例如 UrlEncode 解码则前缀可以指定为`%`。\n不指定前缀则默认前缀为空,使用空前缀时不能混杂任何非 16 进制编码字符。\n如果前缀是单个空白字符时,可以省略字符串开始的前缀(仅作为分隔符使用) string.hex( = 以十六进制编码字符串 string.hex(.(字符串,前缀,'\x80') = 以十六进制编码字符串中的所有非ASCII字符 - 字节码大于等于'\x80'的字节(汉字等),\n指定忽字符时则,前缀参数不可省略,不可指定空前缀。 string.hex(.(字符串,前缀,忽略字符串) = 以十六进制编码字符串。\n前缀可包含一个或多个字符。\n如果不指定忽略字符则前缀可省略,默认前缀为空字符串。\n忽略字符串指定忽略不转换的字符,不指定则编码所有字节。\n指定了任意忽略字符,都会忽略 ASCII 大小写字母以及 ASCII 数字。 string.unescape(__) = 还原函数 string.escape 生成的转义字符串\n可兼容JSON字符符转义规则,允许直接包含单引号 string.escape( = 转义字符串中需要转义的字符\n使用string.unescape函数可以还原转义 string.escape(.(字符串) = 返回转义字符串,如果字符串不需要转义返回null\n如果参数@1指定 buffer,即使不需要转义也会返回字符串而不是null string.escape(.(字符串,兼容JSON,Unicode编码) = 返回转义字符串,如果字符串不需要转义返回 null,\n如果参数@1指定 buffer,即使不需要转义也会返回字符串而不是null,\n如果参数@2为true,即使字符串不需要转义也会返回字符串而不是 null\n兼容 JSON 时参数1 应当是 UTF8、或 UTF16 编码文本,单引号转为`\u0027`,\nUnicode 编码为 true 时所有非 ASCII 字符使用 `\uXXXX `编码\n\n注意即使选择了不启用 UNICODE 编码,单引号,\n以及一些可能无法直接显示的 Unicode 字符仍然会进行转义 string.cmp(.(字符串,字符串2,比较长度) = 参数可以是字符串或 buffer\n文本模式比较字符串前n个字符串大小,忽略大小写,忽略区域设置,\n从第一个字符开始比较,不相等或不支持比较的数据类型返回非0值,\n字符串1较大返回正数,字符串2较大返回负数\n比较长度是可选参数,默认为字符串长度\n仅比较纯文本,忽略'\0'以后的内容 string.collate(.(字符串,字符串2) = 比较字符串,大小写敏感,相等返回0,\n字符串1较大返回正数,字符串2较大返回负数,\n排序受区域影响,使用setlocale函数改变区域设置\n该函数需要转换为UTF16比较,性能不及使用大于、小于等操作符直接比较字符串 string.load( = 读取文件或内嵌资源文件,返回普通字符串\n如果文件以UTF16 LE BOM开始,并且长度为2的倍数时,读入为Unicode(UTF16)字符串\n\n注意,此函数以启用共享读写模式打开文件 string.load(.("文件路径") = 以二进制模式读取文件或内嵌资源文件,返回普通字符串。\n\n路径开始可用单斜杠(或单反斜杠)表示应用程序根目录,前面再加`~`表示 EXE 根目录。\n如果`~\`或`~/`开头的EXE根目录路径不存在,自动转换为应用程序根目录下的路径重试。 string.load(.(资源名,资源类型,dll句柄) = 读取文件或内嵌资源文件,返回普通字符串\n资源名,资源类型都可以是字符串、或小于0xFFFF的数值或指针\n参数三是dll句柄,默认为_HINSTANSE\n除参数一以外,其他参数可选 string.loadBuffer( = 读取文件或内嵌资源文件,返回 buffer\n\n注意,此函数以启用共享读写模式打开文件 string.loadBuffer(.("文件路径") = 读取文件或内嵌资源文件,返回 buffer,\n\n路径首字符可用斜杠表示应用程序根目录,用~加斜杠表示EXE根目录\n如果`~\`或`~/`开头的EXE根目录路径不存在,自动转换为应用程序根目录下的路径重试 string.loadBuffer(.(资源名,资源类型,dll句柄) = 读取文件或内嵌资源文件,返回 buffer,\n资源名,资源类型都可以是字符串、或小于0xFFFF的数值或指针\n参数三是dll句柄,默认为_HINSTANSE\n除参数一以外,其他参数可选 string.save("__/*请输入文件路径*/", ) = 保存字符串到文件\n如果父目录尚未建立,将自动创建父目录\n写入文件成功返回true,否则返回false,错误信息\n如果文件存在隐藏属性,可能会写入失败,错误信息返回"No Error"\n\n注意,此函数以启用共享读写模式打开文件 string.save("__/*请输入文件路径*/", ,true) = 追加字符串到文件\n如果父目录尚未建立,将自动创建父目录\n\n注意,此函数以启用共享读写模式打开文件 string.crc32(.(字符串,crc32,长度) = 计算字符串的CRC32校验值\n参数一也可以是 buffer,\n可选使用参数@2指定前面字符串的校验值,以返回总的校验值\n长度为可选参数 string.repeat(.(count) = 创建长度为 @count 的字符串,默认填充所有字节的字节码设为 0 。\n长度为 0 也会返回空字符串而非 null 值。 string.repeat(.(repCount,repString) = 返回将原字符串( @repString )重复指定次数( @repString )后拼接而成的新字符串 。 string.repeat(.(count,byteCode) = 创建长度为 @count 的字符串,填充所有字节的字节码为参数 @byteCode 指定的值。\n字节码是一个数值,可用单引号包围的字符串并加 # 后缀取首字节的字节码,例如 'A'# 。 string.split( = 拆分字符串,\n空字符串拆分后返回数组长度为0,\n连续的分隔符中间拆分为空字符串,\n改用string.splitEx函数才能使用模式语法指定连续的分隔符 string.split(.('字符串') = 不指定分隔符则按UTF8编码逐个拆分为字符数组,\n返回数组,中文等多字节字符会被拆分为一个数组元素,\n参数传入空字符串返回数组长度为0 string.split(.('字符串','A',返回数组最大长度) = 单字节快速拆分\n返回数组,空字符串返回数组长度为0\n参数@3为可选参数,不指定则拆分全部字符串 string.split(.('字符串','abc',返回数组最大长度) = 指定多个单字节分隔符,不可使用多字节分隔符,基于二进制搜索\n返回数组,空字符串返回数组长度为0\n参数@3为可选参数,不指定则拆分全部字符串 string.split(.('字符串','<分隔符>',返回数组最大长度) = 置于`<>`内的字符串作为分隔符,\n返回数组,空字符串返回数组长度为0\n参数@3为可选参数,不指定则拆分全部字符串 string.join(.(字符串数组,"分隔字符串",开始索引,结束索引) = 将字符串数组使用指定的分隔符合并为一个字符串。\n即使传入空数组至少也会返回空字符串而非 null。\n参数@1如果是包含 buffer 的数组则不应使用此函数,而应改用 raw.join 函数。\n起始索引与结束索引为可选参数,可传入负数表示自数组尾部倒计数 string.concat(.('字符串','字符串',->->->) = 拼接并返回字符串,支持任意个参数,\n允许参数中有null值,所有参数为null或无参数时无返回值,\n二进制模式拼接,不会被'\0'截断 string.concat(.(buffer,'文本字符串',->->->) = 文本模式追加字符串到 buffer,buffer 请使用 raw.buffer 函数创建,\n如果需要使用二进制模式拼接字符串到 buffer,请使用 raw.concat() 函数\n\n可以追加任意个数的字符串参数,字符串参数也可以是null值。\n仅拼接'\0'以前的纯文本,超出 buffer长度的内容将被丢弃。 string.reverse(.('字符串') = 字节序反转排列 string.reverse(.('字符串',true) = 将字符串倒序排列\n以字符为单位,参数必须是以UTF8编码的文本字符串,\n返回值同样是UTF8编码,注意aardio中文本字符串默认的编码为UTF8 string.unpack(.(str,i,j) = 取字符串的第i个到第j个字符的ascii码数值并返回。 string.unpack(.(str,i) = 取字符串的第i个字符的ascii码数值。 string.pack(.(chr__,chr2) = 参数为零个或多个字符的ascii码数值\nstr = string.pack('A'#,'B'#,'C'#)\n也可以是一个包含字节码的数组,例如:\nstring.pack( {'A'#,'B'#,'C'# } ) string.fromCharCode(__) = 将一个或多个 Unicode 码点( char's code point )转换为字符,\n返回 UTF-8 编码的字符串。\n\n参数可指定一个或多个 Unicode 码点(支持大于 0x10000 的编码 ),\n也可以指定一个包含 Unicode 码点的非空数组作为参数。 string.charCodeAt( = 返回 UTF8 编码的文本指定位置字符的 Unicode 码点( char's code point )。\n此函数以字符为单位计数而不是以字节为单位计数,一个字符可能包含多个字节。\n无论字符的 Unicode 码点是否大于 0x10000 都计为一个字符单位。\n\n注意 UTF8 属变长编码,因此每次调用此函数都需要从文本开始计算字符位置。\n如果需要处理所有字符,建议先使用 string.split 将字符串一次性拆分为字符数组。 string.charCodeAt(.(字符串,字符位置) = 省略字符位置时默认值为 1 ,1 表示第 1 个字符,\n一个字符可能包含多个字节。\n\n注意 UTF8 属变长编码,因此每次调用此函数都需要从文本开始计算字符位置。\n如果需要遍历所有字符,可使用 tring.split 一次性拆分所有字符到数组。 string.charAt( = 返回 UTF8 编码文本指定位置的字符,\n此函数以字符为单位计数而不是以字节为单位计数,一个字符可能包含多个字节。\n无论字符的 Unicode 码点是否大于 0x10000 都计为一个字符单位。\n\n注意 UTF8 属变长编码,因此每次调用此函数都需要从文本开始计算字符位置,\n如果需要处理所有字符,建议先用 string.split 将字符串一次性拆分为符数组。 string.charAt(.(字符串,字符位置) = 省略字符位置时默认值为 1, 1 表示第 1 个字符,\n此函数以字符为单位计数而不是以字节为单位计数。 string.lower(__) = 字符串转换为小写 string.upper(__) = 字符串转换为大写 string.random( = 基于 math.random 随机数生成随机字符串。\n[使用手册相关文档](doc://library-guide/builtin/string/rand.md) 。\n如果需要使用安全随机数生成随机字符串请使用 crypt.random 库。 string.random(.(len) = 生成随机字符串(字母、数字)。\n如果需要使用安全随机数生成随机字符串请使用 crypt.random 库。 string.random(.(len,"中文字符集") = 生成随机字符串,并指定随机字符集 string.random(.(str,str2,str3) = 参数为多个字符串,函数随机返回其中一个字符串 string.slice(.(str,i,j) = 从字符串中截取位置i到j的字符串,\n注意i使用1表示第一个字符,返回字符串包含j指字的最后一个字符,\n按字节计数,汉字为多个字节,如果i,j为负数则从右侧倒数计数\n省略参数j则默认值为截取到字符串尾部\n\n参数@1也可以是 buffer 对象 string.slice(.(str,i,j,true ) = 从字符串中截取位置i开始的字符串,\n注意i使用1表示第一个字符,返回字符串包含j指字的最后一个字符,\n按字符计数,汉字为一个字符,如果i为负数则从右侧倒数计数\n省略参数j则默认值为截取到字符串尾部,\n\n参数@1也可以是 buffer 对象 string.left(.(str,lengthOrNegFromEnd) = 从字符串左侧截取 @lengthOrNegFromEnd 个字节,\n按字节计数,汉字为多个字节。\n@lengthOrNegFromEnd 为负数表示自左侧截取到右侧倒计数的那个字节。\n参数 @str 也可以指定 buffer 对象 string.right(.(str,lengthOrNegFromBegin) = 从字符串右侧截取 @lengthOrNegFromBegin 个字节,\n@lengthOrNegFromBegin 为负数表示自左侧计数的起始位置,并向右截取剩余的所有字节。\n按字节计数,汉字为多个字节\n参数 @str 也可以是 buffer 对象 string.left(.(str,lengthOrNegFromEnd,true) = 从字符串左侧截取 @lengthOrNegFromEnd 个字符,\n按字符计数,汉字为一个字符。\n@lengthOrNegFromEnd 为负数表示自左侧截取到右侧倒计数的那个字符。\n参数 @str 也可以是 buffer 对象 string.right(.(str,lengthOrNegFromBegin,true) = 从字符串右侧截取 @lengthOrNegFromBegin 个字符\n按字符计数,汉字为一个字符。\n@lengthOrNegFromBegin 为负数表示自左侧计数的起始位置,并向右截取剩余的所有字符。\n参数 @str 也可以是 buffer 对象 string.trim(.(str,' ') = 从字符串首尾清除指定的一个或多个单字节字符 string.trim(.(str) = 从字符串首尾清除所有空白字符 string.trimleft(.(str,' ') = 从字符串左侧清除指定的一个或多个单字节字符\n清除多字节字符请不要用这个函数,应改用模式匹配替换,例如\nstr = string.replace(str,"^[中文]+",``) string.trimleft(.(str) = 从字符串左侧清除所有空白字符 string.trimright(.(str,' ') = 从字符串右侧清除指定的一个或多个单字节字符\n清除多字节字符请不要用这个函数,应改用模式匹配替换,例如\nstr = string.replace(str,"[中文]+$",``) string.trimright(.(str) = 从字符串右侧清除所有空白字符 string.format("%__", ) = 首参数内每个%符号后是一个格式化字符,\n每个格式化字符按对应顺序格式后续参数\n\n详细用法请参考\n[格式化字符串](doc://library-guide/builtin/string/format.md) string.toUtf16( = 转换字符串到 UTF16 编码字符串。\n如果字符串已经是 UTF-16 编码将直接返回参数。 \n如果转换成功将自动设置字符串的 UTF 标记以避免重复转换。\n对 UTF-16 字符串使用下标操作符 `[]` 可返回 2 字节的宽字节码,\n使用直接下标操作符`[[]]`会返回 2 字节的宽字符 string.toUtf16(.(字符串,源编码,转换字节数) = 字节数为 -1 时表示查找'\0'终止符自动获取长度。\n指定转换字节数时,参数 @ 即可使用指针、buffer 作为参数\n注意参数 @3 始终以字节计数,而非按字符计数。\n源编码参数是表示代码页的数值,例如 65001 表示 UTF-8 编码。 string.toUtf16(.(字符串,源编码) = 将字符串转换从指定编码转换为 UTF-16 编码。\n源编码参数是表示代码页的数值,省略则默认为 65001(UTF-8 代码页)。 string.fromUtf16( = 将参数 @1 指定的字符串字符串自 UTF-16 编码转换为指定编码,默认转为 UTF-8,\n如果参数 @1 是一个字符串,并且已存在 UTF 编码标记,\n则根据 UTF 标记进行优化并避免不必要的转换或错误转换。\n如果出现错误转换,请注意检查源数据是否被添加了错误的 UTF 标记 string.toUtf16(.(字符串) = 将字符串转换从指定编码转换为 UTF16 编码\n源编码默认为 UTF-8 代码页 65001 string.fromUtf16(.(字符串,目标编码,转换字符数) = 显示定转换转换字符数参数时,\n可允许第一个参数为指针、或 buffer对象,\n参数@3以字符计数,即2个字节为一个单位,\n目标编码参数需要指定一个表示代码页的数值,例如 65001 为 UTF-8 代码页。\n字符数为 -1 表示查找'\u0000'终止符获取可打印文本长度。\n字符数只能为数值。 string.fromUtf16(.(字符串,目标编码) = 从 UTF-16 编码还原到指定编码\n目标编码编码参数是表示代码页的数值,省略则默认为 65001(UTF-8 代码页)。 \n注意aardio中Unicode指的UTF16 LE,代码页为1200\naardio字符串默认为UTF8编码 string.fromUtf16(.(字符串) = 从 UTF-16 编码还原到 aardio 字符串默认的 UTF-8编码。\n注意 aardio 中 UTF16 默认指的是 UTF16 LE,代码页为 1200 string.fromUtf16If(.(字符串) = 如果是 UTF16 字符串转换到 UTF-8 代码页,否则直接返回。\n使用字符串的 UTF 标记判断 UTF-16 字符串,不检测实际编码 string.fromto( = 转换传入文本字符串编码并返回转换后的字符串,\n此函数先调用 string.toUtf16,再调用 string.fromUtf16,\nfromto 函数名源于这两个函数的前缀。 string.fromto(.(字符串,源编码,目标编码) = 转换传入文本字符串编码并返回转换后的字符串,\n编码参数请指定表示代码页的数值,例如 65001 为 UTF-8 编码的代码页。\n目标编码默认为 0 ,即系统默认代码页。\n源编码为可选参数,默认为 UTF-8 代码页 65001。\n如果字符串已存在UTF标记,则忽略源编码参数\nUTF16 LE代码页为1200,UTF 16 BE代码页为1201 string.fromto(.(内存指针,源编码,目标编码,转换字节数) = 转换传入文本字符串编码并返回转换后的字符串,\n编码参数请指定表示代码页的数值,例如 65001 为 UTF-8 编码的代码页。\n参数 @4 为可选用一个数值指定需要转换的文本所占内存字节数,\n字节数为-1时表示查找'\0'终止符自动获取长度。\n指定转换字节数时,参数 @1 即可使用指针、buffer作为参数。\n注意即使指定 UTF-16 代码页,参数 @4 仍然是以字节计数 string.isUtf16(__) = 判断参数是否标记为 UTF-16 编码的字符串。\n此函数仅检测 UTF 标记,不会分析实际编码。\n'在 aardio 转义字符串中附加 u 后缀创建 UTF-16 编码的字符串'u\n有编码转换功能的函数也会自动设置 UTF 标记。\n注意 UTF16 在 aardio 中特指 UTF16 LE,代码页为 1200。 string.isUtf8(__) = 判断参数是否标记过为 UTF-8 编码的字符串。\n此函数仅检测 UTF 标记,如果要检测实际编码请改用 string.len 函数。\naardio 字符串默认为 UTF-8 编码,代码页为 65001。\n原样字符串(raw string)、注释字符串会默认将 UTF 标记设为 UTF-8。\n有编码转换功能的函数也会在转换成功后更新字符串的 UTF 标记。 string.indexAny( = 在字符串内搜索任意单字节字符。 string.indexAny(.(字符串,查找字符串) = 在参数 @1 指定的字符串内查找参数 @2 指定的字符串中的任意一个单字节。\n参数 @2 也可以是数值字节码。\n参数@2 可包含 '\0' 或指定为 0,'\0'#。 string.indexAny(.(字符串,查找字符串,开始位置) = 在参数 @1 指定的字符串内查找参数 @2 指定的字符串中的任意一个单字节,\n参数 @2 也可以是数值字节码。\n参数@2 可包含 '\0' 或指定为 0,'\0'#。 string.lastIndexAny(.(字符串,查找字符串) = 自尾部向前查找参数 @2 指定的字符串中的任意一个字节。\n参数 @2 也可以指定数值字节码。\n参数@2 可包含 '\0' 或指定为 0,'\0'#。 string.lastIndexAny(.(字符串,查找字符串,开始位置) = 自尾部向前查找参数 @2 指定的字符串中的任意一个字节。\n参数 @2 也可以指定数值字节码。\n参数@2 可包含 '\0' 或指定为 0,'\0'#。 string.startsWith(.("字符串","开始串") = 判断开始串是否位于字符串开始处\n基于二进制模式 string.endsWith(.("字符串","结束串") = 判断结束串是否位于字符串结束处\n基于二进制模式 string.startsWith(.("字符串","开始串",true) = 判断开始串是否位于字符串开始处。\n基于文本模式,忽略大小写 string.endsWith(.("字符串","结束串",true) = 判断结束串是否位于字符串结束处。\n基于文本模式,忽略大小写 string.find( = 使用模式串在字符串中查找子串的位置,\n如果有多个捕获分组,将附加为多个返回值。\n如果只是查找普通查找建议使用string.indexOf函数。\n类似的函数 raw.find 可以支持在内存指针中查找字符串 string.find(.("字符串","@查找文本",开始位置,返回值以字符计数) = 返回匹配结果的起始,结束位置\n查找文首字符为'@'或'@@'禁用模式语法\n首字等为'@'可选指定返回位置以字符计数\n`@@`则是`<@@...@>`的缩写形式,忽略大小写查找 string.find(.("字符串","模式",开始位置) = 开始位置为可选参数,默认为1,必须以字节计数,\n函数返回匹配结果的起始,结束位置,以及所有捕获分组 string.replace( = 使用模式匹配查找并替换字符串。\n此函数不会改变原字符串,而是返回替换后的新字符串。\n此函数有两个返回值,第二个返回值为替换次数 string.replace(.("字符串","模式串",替换字符串,替换次数) = 使用模式匹配在字符串中查找替换\n替换字符串,可使用 `\1` 至`\9`引用匹配分组,`\0`表示匹配到的完整字符\n\n替换次数省略则全局替换\n返回值为替换后的新字符串 string.replace(.("字符串","模式串",替换表,替换次数) = 使用模式匹配在字符串中查找替换\n替换表对象中键为匹配到的字符串,替换值可以是字符串、数值、函数、false\n其中数值转换为字符串返回,false表示取消替换,\n函数用于接收匹配结果并返回新字符串,有几个匹配分组就有几个回调参数 string.replace(.("字符串","模式串",替换函数,替换次数) = 使用模式匹配在字符串中查找替换\n替换回调函数返回需要替换的新字符串,不返回值则保留原字符串\n有几个匹配分组就有几个回调参数\n\n替换次数省略则全局替换\n返回值为替换后的新字符串 string.replace(.("字符串","@查找字符串","替换字符串",替换次数) = 禁用模式匹配替换,\n在查找串中用模式匹配语法,替换字符串反斜杠也仅仅表示字面值不再表示匹配分组,\n以`@@`开始则是`<@@...@>`的缩写形式,忽略大小写查找\n替换次数省略则全局替换 string.match( = 使用模式串在字符串中查找子串,\n类似的函数 raw.match 可以支持在内存指针中查找字符串 string.match(.("字符串","模式串",开始位置) = 使用模式串在字符串中查找子串,\n参数@1指定目标字符串,参数@2指定查找模式串。\n参数@3可选,用于指定起始位置,负数表示尾部倒计数,\n返回匹配字符串,如果使用了匹配分组则返回多个对应的匹配串,\n返回值的顺序对应模式串中左圆括号的开始顺序 string.str( = 转换字符串为不包含`'\0'`的纯文本字符串,\n或转换 UTF-16 字符串(ustring)为不包含`'\u0000'`的纯文本字符串 string.str(.(字符串) = 如果传入字符串包含 `'\0'`,则返回 `'\0'` 前面的字符串,\n否则返回原字符串。\n\n参数@1也可以是 buffer 对象, \n如果输入参数是结构体或指针,应当改用 raw.str 函数 string.str(.(字符串,true) = 参数 @1 可传入 UTF-16 字符串(ustring)。\n UTF-16 字符串(ustring)如包含 `'\u0000'`,\n则返回 `'\u0000'` 前面的 UTF-16 字符串(ustring),否则直接返回原字符串。\n返回的字符串自动设置 UTF 标记为 UTF-16 。\n\n如果参数 @1 是已经设置 UTF 标记为 UTF-16 的字符串(ustring),参数 @2 可以省略。\n参数 @1 也可以是 buffer 对象,如果参数是结构体或指针。\n应改用 raw.str 函数 string.gmatch(str,pattern) = @for m in string.gmatch( ,".__/*指定模式串,\n用于在参数@1指定的字符串中循环全局搜索符合条件的字符串,\n有几个匹配分组迭代器返回几个值,\n注意表达式不能以^开始*/"){ \n \n} string.lastIndexOf( = 从右侧反向搜索字符串,禁用模式匹配。\n这个函数需要从尾部逐个字符反向查找,效率较低 string.lastIndexOf(.("字符串","查找子串",搜索范围) = 从右侧反向搜索字符串。\n此函数为二进制搜索,搜索内容可包含'\0',禁用模式匹配\n搜索范围仍然是自左向右(尾部)按字节计数,负数为反向计数。\n返回值仍为左向右(尾部)按字节计数。 string.indexOf( = 纯文本搜索,\n类似的函数 raw.indexOf 支持以二进制直接使用指针搜索内存 string.indexOf(.("字符串","查找文本") = 返回查找文本所在起始索引,结束索引。\n字符串如果包含'\0'时仅取'\0'之前的纯文本\n禁用模式匹配 string.indexOf(.("字符串","查找文本",开始位置,结束位置) = 返回查找文本所在起始索引,结束索引\n字符串如果包含'\0'时仅取'\0'之前的纯文本\n禁用模式匹配 string.len(.(字符串,起始字节位置,结束字节位置) = 如果字符串是合法的 UTF-8 编码,返回字符计数,\n参数@2,@3都是可选参数,以字节而非字符为单位\n起始位置默认为1\n结束位置默认为-1 string.len( = 如果字符串是合法的UTF8编码,返回字符计数,否则返回0 string.bytes( = 将字符记数转换为字节计数 string.bytes(.(字符串,字符数,开始位置) = 将字符记数转换为字节计数\n可选用参数@3指定开始位置,此参数以字节为单位,首字节开始为1\n如果遇到不合法的UTF8编码函数返回0 string.getUtf(__) = 获取字符串的UTF格式标记,返回值如下:\n&&16 表示双字节编码的UTF-16编码\n&&8 表示UTF-8字符串,\n&&(8 | 1) 表示UTF-8、ANSI兼容编码,即所有字符小于0x80\n\n对于空字符串,aardio忽略其UTF标记,\n对于非空字符串,aardio只允许一个字符串对象在创建时初始化UTF标记为UTF16,\n而其他字符串,允许在运行时修改UTF标记 string.setUtf( = 设置字符串的UTF格式标记\n该标记主要由aardio自动设置,一般不建议用户调用该函数\n\n对于空字符串,aardio忽略其UTF标记,\n对于非空字符串,aardio只允许一个字符串对象在创建时初始化UTF标记为UTF16,\n而其他非UTF16字符串,允许在运行时修改UTF标记,\n此函数并不会改变字符串数据,也没有返回值 string.setUtf(.("字符串",编码格式) = 设置字符串的UTF格式标记,所有UTF格式标记如下:\n0 表示普通字符串,\n&&8 表示UTF-8字符串,\n&&16 表示 UTF-16 字符串(ustring)。\n&&(8 | 1) 表示UTF-8、ANSI兼容编码,即所有字符小于0x80\n\n此函数只能用于标记除UTF16以外的编码。\n不能使用此函数修改字符串的UTF标记为UTF16编码,\n也不允许使用此函数修改已经标记为UTF16编码的字符串。\n\naardio会自动维护UTF16字符串的编码标记,\n使用string.sliceUtf16函数也可以获取UTF16标记的字符串 string.sliceUtf16( = 截取 UTF-16 字符串,\n也可用于为字符串添加 UTF-16 标记 string.sliceUtf16(.(字符串,开始位置,结束位置) = 截取 UTF-16 字符串,也可用于将字符串 UTF 标记设置为 UTF-16 .\n此函数不会修改传入字符串的 UTF 标记,但是返回非空字符串时会其 UTF 编码标记设为 UTF-16。\n\n注意此函数并不是一个编码转换函数,\n转换编码请使用 string.toUtf16 函数.\n\n开始位置,结束位置以 UTF-16 字符单位计数(2个字节为1个单位)\n可以使用负数表示自右侧倒计数单位,-1 表示最后一个字符. raw.loadDll( = 加载 DLL\nDLL变量名如果为全局变量,首字母必须大写且必须按如下格式赋值\n::User32 := raw.loadDll("User32.dll")\n\n如果DLL厂商仅提供一个版本的DLL,一般是32位的DLL,在aardio可以直接加载,\n如果DLL厂商提供了64位、32位两个版本的DLL,这时候你需要选择32位版本的DLL才能加载,\naardio程序也是32位的,主要是因为64位程序只能运行在64位平台,而32位程序兼容所有平台。\n\n32位的进程的内存限制仅仅是限制单个进程的内存,\n实际上一般的桌面软件基本都不可能用到好几个GB的内存\n目前aardio提供process.command可以很方便的使用使用多进程交互\n如果软件使用外部数据库、或者其他服务端口,因为跨进程都不会受单进程的内存限制。\n编写网站的FastCGI同样是多进程模式。 raw.loadDll(.("DLL路径","共享名字","调用约定") = 第一个参数可以是DLL路径或DLL内存数据,\n载入内存DLL数据时,可使用第二个参数指定共享模块名称以启用共享模式,\n如果DLL本身是库文件,则共享名称应使用库命名空间路径.\n参数@3可选指定调用约定,默认为"stdcall,microsoft"\n\n\n路径首字符可用斜杠表示应用程序根目录,用~加斜杠表示EXE根目录\n如果`~\`或`~/`开头的EXE根目录路径不存在,自动转换为应用程序根目录下的路径重试,\n\n如果DLL文件依赖同目录下的其他DLL文件,而这些DLL不在默认搜索目录顺序内时,\naardio将会调用::Kernel32.SetDllDirectory()自动修正该问题,\n并在操作完成后自动恢复默认设置 raw.loadDll() = !dllModule. raw.tofastcall( = 创建 ms-fastcall 调用约定的原生回调函数\n注意前两个参数不能大于32位,\n\n应保持原生回调函数在有效作用域内,否则会自动释放,\n函数返回值应当先赋值到变量而不是直接写到调用参数里,\n这会导致函数未返回但原生回调函数可能已释放。\n\n如果原生回调函数被指定为某对象的成员,在函数内部又循环引用了该对象,\n这会导致无法释放资源。使用参数@3将该对象指定为owner可避免该问题 raw.tofastcall(.(函数,"int()",owner) = 参数@2与API声明语法相同,可使用&&表示输出参数,\n例如C中的int *指针在aardio回调中声明为int &&\n有几个输出参数,就可增加相应个数的返回值用于更新输出参数值,\n未返回的输出结构体参数忽略不更新传入的结构体。\n\n回调参数声明可直接指定结构体,传入实参必须是结构体指针,\n结构体声明不能再嵌套结构体,不能包含变量,\n示例:`raw.tocdecl(func,"int({int x;int y} &&pt)")`\n\n返回值类型检测比输出参数宽松,数值,布尔值、null值可按C规则兼容转换,\n返回值传结构体时必须返回不大于64位的结构体,且传值而非传址 raw.tostdcall( = 创建stdcall调用约定的原生回调函数,\n\n应保持原生回调函数在有效作用域内,否则会自动释放,\n函数返回值应当先赋值到变量而不是直接写到调用参数里,\n这会导致函数未返回但原生回调函数可能已释放。\n\n如果原生回调函数被指定为某对象的成员,在函数内部又循环引用了该对象,\n这会导致无法释放资源。使用参数@3将该对象指定为owner可避免该问题 raw.tostdcall(.(函数,"int()",owner) = 参数@2与API声明语法相同,可使用&&表示输出参数,\n例如C中的int *指针在aardio回调中声明为int &&\n有几个输出参数,就可增加相应个数的返回值用于更新输出参数值,\n未返回的输出结构体参数忽略不更新传入的结构体。\n\n回调参数声明可直接指定结构体,传入实参必须是结构体指针,\n结构体声明不能再嵌套结构体,不能包含变量,\n示例:`raw.tocdecl(func,"int({int x;int y} &&pt)")`\n\n返回值类型检测比输出参数宽松,数值,布尔值、null值可按C规则兼容转换,\n返回值传结构体时必须返回不大于64位的结构体,且传值而非传址 raw.tocdecl( = 创建cdecl调用约定的原生回调函数,\n\n应保持原生回调函数在有效作用域内,否则会自动释放,\n函数返回值应当先赋值到变量而不是直接写到调用参数里,\n这会导致函数未返回但原生回调函数可能已释放。\n\n如果原生回调函数被指定为某对象的成员,在函数内部又循环引用了该对象,\n这会导致无法释放资源。使用参数@3将该对象指定为owner可避免该问题 raw.tocdecl(.(函数,"int()",owner) = 参数@2与API声明语法相同,可使用&&表示输出参数,\n例如C中的int *指针在aardio回调中声明为int &&\n有几个输出参数,就可增加相应个数的返回值用于更新输出参数值,\n未返回的输出结构体参数忽略不更新传入的结构体。\n\n回调参数声明可直接指定结构体,传入实参必须是结构体指针,\n结构体声明不能再嵌套结构体,不能包含变量,\n示例:`raw.tocdecl(func,"int({int x;int y} &&pt)")`\n\n返回值类型检测比输出参数宽松,数值,布尔值、null值可按C规则兼容转换,\n返回值传结构体时必须返回不大于64位的结构体,且传值而非传址 raw.convert(.(源指针,目标结构体,字节单位偏移,结构体单位偏移) = 读取内存数据到目标结构体,返回目标结构体,\n参数@1可以是指针、buffer、字符串,\n可选用参数@3指定在源指针上按字节单位计数的偏移位置,不指定默认为0,\n如果在参数@4指定了按结构体为单位大小的偏移位置,则忽略参数@3 raw.convert(.(源结构体,目标指针,字节单位偏移,结构体单位偏移) = 把结构体写入内存,返回内存指针,\n参数@2可以是指针、buffer,\n可选用参数@3指定在目标指针上按字节单位计数的偏移位置,不指定默认为0,\n如果在参数@4指定了按结构体为单位大小的偏移位置,则忽略参数@3 raw.convert(.(源结构体,目标结构体) = 转换结构体,返回目标结构体 raw.convert( = 转换并返回结构体 raw.remoteApi( = 在外部进程内创建远程调用函数 raw.remoteApi(.(目标进程,"void()",CALL地址,调用约定) =参数(进程ID或句柄,函数原型,CALL地址,调用约定) \n参数@1可以是进程ID,也可以是进程句柄(此函数不负责关闭该句柄)\n注意参数@1不能指定当前进程ID或句柄,\n不指定调用约定在数时默认使用stdcall调用约定 raw.remoteApi(.(目标进程,"void()","dll名","函数名") = 参数(进程ID或句柄,函数原型,加载DLL模块名,函数名,调用约定) \n不指定调用约定时默认使用stdcall调用约定\n不会在API函数名字后面自动添加或移除"A","W"编码声明后缀,\n并且要注意搜索DLL时默认搜索路径包含目标EXE所在目录,而非当前EXE目录 raw.remoteApi(.(目标进程,"void()","dll名","函数名","cdecl") = 参数(进程ID或句柄,函数原型,加载DLL模块名,函数名,调用约定) \n不会在API函数名字后面自动添加或移除"A","W"编码声明后缀,\n并且要注意搜索DLL时默认搜索路径包含目标EXE所在目录,而非当前EXE目录 raw.remoteApi(.(目标进程,"void(INT thisAddr)","dll名","函数名","thiscall") = 参数(进程ID或句柄,函数原型,加载DLL模块名,函数名,调用约定)\nthiscall使用第一个参数指定this指针地址\n不会在API函数名字后面自动添加或移除"A","W"编码声明后缀,\n并且要注意搜索DLL时默认搜索路径包含目标EXE所在目录,而非当前EXE目录 raw.realloc( = 快速分配内存并返回动态指针\naardio会在"动态指针"头部倒退8个字节记录内存以及存储内容长度,\n动态指针的头部结构体如下:\n\n```aardio\n{\n INT capacity;//记录预分配的内存容量\n INT size;//记录存储的数据长度\n}\n```\n\n动态指针指向的内存尾部隐藏2个字节并放置'\u0000'(不计入内存长度)\n"动态指针"可作为普通指针使用,并可用于 raw.concat 函数快速拼接数据\n使用此函数将"动态指针"的长度设为0时可释放内存\n"动态指针"不会被自动回收,必须手动释放 raw.realloc(.(内存长度) = 快速分配内存并返回指针,\n可选用参数3指定分配内存中所有字节的初始值\n初始值可指定所有字节的字节码,也可指定字符串、结构体\n返回分配的指针,该指针可作为普通指针使用\n指针不会被自动回收,必须手动释放 raw.realloc(.(内存长度,动态指针,初始值) = 调整内存大小,可能返回新指针\n传入指针必须弃用,返回值是新的指针必须手动释放,\n可选用参数3指定分配内存中所有字节的初始值,\n初始值可指定所有字节的字节码,也可指定字符串、结构体\n指定初始值会重置指针记录的数据长度\n\n如果指定的初始值为字符串或 buffer,\n并且其长度超过了动态指定已分配的内存长度,\n则aardio会自动截断放不下去的尾部数据。 raw.realloc(.(0,动态指针) = 长度指定为0则释放"动态指针",指针参数为null时忽略不报错\n建议使用传入"动态指针"的变量接收空的返回值,以避免误用失效的指针变量 raw.concat( = 此函数主要用于向 raw.realloc 创建的动态指针追加数据。\n要注意此函数与 string.concat 有较大的区别,string.concat 是拼接旧字符串返回新字符串。\n而 raw.concat 是原地修改第一个参数指定的内存对象( buffer 或动态指针 )。\nraw.concat 应非常谨慎地使用,要特别注意:\n- 如果写入参数 @1 指定的动态指针,则每次都要接收返回的新动态指针并废弃原来的动态指针。\n写入动态指针时,会按需自动分配更大的内存。\n- 如果写入参数 @1 指定的 buffer,则调用者必须提前分配好足够的长度。\nbuffer 是定长的无法改变其大小,raw.concat 也不会创建新的 buffer。\n而且当参数 @1 指定 buffer 时,返回值是写入后的有效数据长度(数值)。\n\n如果目的是拼接 buffer 或字符串并返回新的 buffer 则应改用 raw.join 函数(可拼接 buffer 或字符串数组)。\n如果希望更方便更安全地向动态指针中写入内容,应改用更强大的 string.builder 对象 raw.concat(.(动态指针,追加数据,追加长度) = 追加数据\n参数@1必须是raw.realloc创建的"动态指针"\n如果内存长度不够时,此函数会自动调用raw.realloc调整内存大小\n此函数返回新的"动态指针",传入的动态指针地址可能改变必须弃用\n\n追加数据可以是字符串、buffer、动态指针、普通指针、结构体\n追加长度为可选参数,如果追加数据为指针、或动态指针则必须明确指定追加长度如果\n如果追加参数是字符串、或 buffer,会在尾部添加'\u0000'(不计长度)\n\n可选在第4个参数中指定动态调整指针内存大小时的默认增加长度,该值默认为1024 raw.concat(.(buffer,追加字符串,buffer保留长度,追加长度) = 二进制模式拼接字符串\n文本模式拼接请使用string.concat\n参数@1应为 buffer 对象,\nbuffer保留长度可省略,默认为0\n追加长度可省略,默认为追加字符串长度\n返回拼接后的有效数据长度,有效长度不会超过 buffer大小 raw.sizeof(.(__ ) = 返回结构体、原生类型、动态指针内存长度\n参数可以是结构体、或包含类型名的字符串\n参数如果是指针,则必须是raw.realloc函数创建的动态指针,\n传入动态指针,返回2个值,分别为存储数据长度、分配内存总长度\n传入其他来源指针,因缺少指针头信息会导致崩溃\n传入null值返回0\n无参数报错 raw.buffer( = 创建可读写、固定长度的内存块,用于读写二进制字节串,数据类型为 `buffer`。\n可用下标操作符 `[]` 读写 8 位无符号字节数值,可用 `#` 操作符取数组长度。\n不支持连接操作符 `++`,支持 raw.concat,string.concat,string.join 等拼接函数。\n\n在几乎所有字符串函数中都可以作为字符串使用。\n在结构体中也可作为指针、 `BYTE[]` 数组的值。\n在原生 API 参数中可作为内存指针、字符串、输出字符串使用。\n在 COM 函数中可作为安全数组使用。 raw.buffer(.(initialContent) = 创建可读写、固定长度的内存块,用于读写二进制字节串,数据类型为 `buffer`。\n参数可以是一个结构体、字符串、或 buffer,传入空表 `{}` 返回 null,\n分配新的内存并复制初始值指定的数据,返回 buffer 对象,\nbuffer 在多数字符串函数中都可以作为字符串使用\n在 API 中可以作为字符串、指针、字节串使用。\n在 COM 函数中可作为安全数组使用\n\nbuffer 在 JSON 中会转换为 `{type="Buffer";data=[] }` 格式的表对象,\n这种表对象可作为 raw.buffer 的唯一参数还原为 buffer 对象。 raw.buffer(.(size,initialContent) = 创建可读写、固定长度的内存块,用于读写二进制字节串,数据类型为 `buffer`。\n参数 @size 指定需要分配的内存大小,\n参数 @initialContent 可以使用结构体、指针、buffer、或字符串指定初始填充的数据,\n也可用一个数值指定所有字节的初始字节码,不指定默认初始化所有字节码为 0,\n\n如果初始值指定为字符串或 buffer 类型,\n填充初始数据以后剩余的字节会清零。\n\nbuffer 存储的是二进制字节串,可使用下标操作符读写字节码。\nbuffer 在多数字符串函数中都可以作为字符串使用。\n在原生 API 中可以作为字符串、指针、字节数组使用。 raw.copy( = 复制内存数据 raw.copy(.(destPinterOrBuffer,srcData,size) = 复制内存数据。\n- 参数 @destPinterOrBuffer 指定复制目录,允许指针,buffer 类型参数。\n- 参数 @srcData 允许使用指针,buffer,字符串,或结构体参数。\n此函数不允许其他可自动转换为指针的非指针类型参数。\n- 参数 @size 指定要复制的字节长度。\n\n 如果复制源或目标是 buffer,字符串,或结构体等可获取内存长度的类型,可以省略参数 @size 。\n 如果 aardio 能获取复制源或复制目标的内存长度则复制长度不会超过可用长度。\n 但如果参数是指针将无法检测内存长度,请自行计算好参数避免溢出。\n\n 如果未显式指定复制长度,并且 @srcData 是 buffer,或字符串时,\n 将复制全部数据与尾部隐藏的`\u0000`到目标内存,如果复制目标是指针,\n 那么要保证复制源加上这 2 个字节也不会超过目标内存长度。\n\n为了避免有风险的误操作,此函数不提供偏移量参数。\n如果 srcData 是结构体则改用 raw.convert 函数可指定目标指针偏移量。\n其他情况可以用 raw.toPointer 获得指定偏移量临时指针。 raw.toPointer( = 获取对象的临时指针。\n获取的指针在源对象失效时也会失效,并且无法阻止源对象被回收。\n此函数获取的指针只能临时使用,不应当长久保存,并应当尽快弃用。\n此函数能不用就尽量不要用。 raw.toPointer(.(anyPointerConvertible,offset) = 获取参数 @anyPointerConvertible 的临时指针,可选用参 数@offset 指定偏移值。\n所有可用于 API 函数 pointer 类型的对象都可以用此函数提取指针。\n例如指针、字符串、buffer、所有定义了 _topointer 元方法的对象。\n普通结构体必须转为 buffer 才能提取指针。\n参数 @anyPointerConvertible 不能是数值,数值转指针请改用 topointer 函数。\n\n滥用此函数提取对象的原始指针在很多时候是不必要且不安全的,\n如果在原对象被回收以后,仍然在错误的使用获得的指针,会让程序变得不稳定。\n除非你知道自己在做什么否则请不要使用此函数。\n实际上 buffer, 结构体等对象在很多函数里都可以直接作为指针使用,\n这样更安全、更稳定、代码更简洁,也避免了不必要的函数调用。 raw.tostring(.(__ ) = 将结构体、指针、或 buffer 对象转换为普通字符串\n参数如果是结构体不需要指定截取位置\n参数如果是 buffer 类型,自动获取 buffer 长度并设为截取长度\n参数如果是指针且未指定长度时,以'\0'为终止符并设为截取长度,\n转换为不包含'\0'的文本字符串,建议改用 raw.str 函数 raw.tostring(.(__ , start,end) = 将指针、或 buffer 对象转换为普通字符串\nstart指定开始位置(省略则默认设为1),end指定结束位置,\n\n如果未指定结束位置参数,\n参数如果是buffer类型,自动获取buffer长度并设为结束位置\n参数如果是指针,以'\0'为终止符并设为结束位置 raw.str( = 转换为纯文本字符串(去掉尾部多余终结符)\n参数为空返回null\n\n如果输入参数是字符串,应当改用 string.str 函数 raw.str(.(指针,是否unicode,偏移) = 转换为纯文本字符串(去掉尾部多余终结符)\n参数一可以是指针或buffer,其余参数可省略,偏移默认为0\n参数@2为true反回字符串标记会设置UTF-16标记,否则设为UTF-8标记,\n注意此函数并不会转换编码,不可指定错误的编码参数\n参数为空返回null raw.str(.(结构体,是否unicode) = 结构体内存数据转换为文本字符串\n参数@2为 true 返回字符串标记会设置 UTF-16 标记,否则设为 UTF-8 标记\n注意此函数并不会转换编码,不可指定错误的编码参数 raw.indexOf( = 与 string.indexOf 类似,\n但 raw.indexOf 基于二进制搜索字符串,可查找包含 `'\0'` 的字符串。\n更重要的区别是参数 @1允许使用内存指针,\n并必须使用参数 @2 指定查找数据的内存长度。\n指定错误的指针或长度会导致内存错误,请谨慎使用此函数。 raw.indexOf(.(指针,查找内存长度,查找字符串,起始索引) = 使用模式串在字符串中查找子串的位置,\n参数@1可以使用指针、字符串、或 buffer\n无论指定任何类型,内存长度都不可省略,aardio不会检测指定的内存长度是否错误\n开始位置为可选参数,默认为1,必须以字节计数,\n函数返回匹配结果的起始位置 raw.find( = 用法与string.find相同\n区别是参数@1允许使用内存指针\n并必须使用参数@2指定查找数据的内存长度\n指定错误的指针或长度会导致内存错误,请谨慎使用此函数 raw.find(.(指针,内存长度,"查找模式",开始位置) = 使用模式串在字符串中查找子串的位置,\n参数@1可以使用指针、字符串、或 buffer\n无论指定任何类型,内存长度都不可省略,aardio不会检测指定的内存长度是否错误\n开始位置为可选参数,默认为1,必须以字节计数,\n函数返回匹配结果的起始,结束位置,以及所有捕获分组\n如果有多个捕获分组,将附加为多个返回值 raw.match( = 用法与string.match相同\n区别是参数@1允许使用内存指针\n并必须使用参数@2指定查找数据的内存长度\n指定错误的指针或长度会导致内存错误,请谨慎使用此函数 raw.match(.(指针,内存长度,"模式串",开始位置) = 使用模式串在字符串中查找子串,\n参数@1可以使用指针、字符串、或 buffer,\n无论指定任何类型,内存长度都不可省略,aardio不会检测指定的内存长度是否错误\n参数@3指定查找模式串。\n参数@4可选,用于指定起始位置,负数表示尾部倒计数,\n返回匹配字符串,如果使用了匹配分组则返回多个对应的匹配串,\n返回值的顺序对应模式串中左圆括号的开始顺序 raw.toarray( = 此函数的作用是在运行时创建一个确定长度的原生类型数组。\n也可以直接定义不指定长度的原生数组,并在运行时使用 length 属性改变长度。\n示例:`{ int array[] = { length = 10 } }` raw.toarray(.(arrrayOrLength,rawTypename,fieldName) = 创建一个包含指定长度原生类型数组的结构体。\n参数@1指定数组长度值,也可以指定用于初始化原生数组的 aardio 数组。\n可选参数 @2 指定数组元素类型,默认为"struct",\n可选参数@3指定数组字段名字,默认为"array"。 raw.toarray() = !rawToArrayResult. !rawToArrayResult.? = 请输入 raw.toarray 第三个参数指定的数组字段名。\n默认字段名字为 array raw._release(.(内核对象) = 释放cdata类型内核对象,慎用.\n此函数保证不会重复释放已释放的内核对象,所以参数可以是已释放的内核对象,\n如果参数是cdata类型内核对象,或者参数的_topointer元方法中返回类型内核对象,则调用内核对象的_gc析构函数\n传入null会忽略不执行任何操作\n\n可用于释放cdata类型内核对象、com对象、IUnknown指针、com.interface创建的对象\n不能用于释放table.gc或gcdata创建的cdata对象 raw.closehandle(__) = 关闭句柄资源 raw.swap(.(数值,"INT");= 反向转换整数的大小端字节序\n参数@2指定API数据类型,支持"INT","int","WORD","word",省略则默认为"INT"\n64位整数请使用math.size64对象的swap函数转换 !dllModule.api(.(函数名,函数原型,调用约定,this指针) = 声明API函数,\n返回值为原生函数对象( cdata 类型 ),\n参数@1也可以指定导出函数名,或用数值指定导出函数序号\n调用约定可省略,默认为stdcall\nthis指针为可选参数,指定该参数以后在调用时可省略首参数 !dllModule.api(.(函数地址,函数原型,调用约定,this指针) = 如果模块是当前进程,\n参数@1可用指针或数值指定原生函数的内存地址,\n返回值为原生函数对象( cdata 类型 ),\n\n调用约定可省略,默认为stdcall\nthis指针为可选参数,指定该参数以后在调用时可省略首参数 !dllModule.api(.(导出符号名) = 仅指定一个参数时,\n直接返回导出符号指针而非返回原生函数对象。\n不会对参数 @1 自动添加或移除 A,W 尾标,\n而是精确匹配导出符号名。\n\n此操作不会增加DLL的引用计数,在使用导出符号指针时DLL变量应在生存周期内 !dllModule.api("__/*输入函数名字*/","void()" ) = 声明API函数,参数(函数名,函数原型,调用约定="stdcall,microsoft")\n可选使用参数3指定调用约定,默认值为"stdcall,microsoft",\n返回值为原生函数对象( cdata 类型 ) !dllModule.api("__/*输入函数名字*/","void()" ,"cdecl") = 声明API函数,参数(函数名,函数原型,调用约定)\n参数3使用一个字符串指定调用约定,逗号后面可选指定开发工具厂商,\n返回值为原生函数对象( cdata 类型 ) !dllModule.gethandle() = 返回模块句柄 !dllModule.? = 可不用声明直接在此输入函数名并调用API函数\n\n一、传入参数规则:\n1、调用约定在加载DLL的参数中指定,支持cdecl不定个数参数\n2、null参数不可省略\n3、32位整数类型,小于32位的整数、以及枚举类型都可以直接在API参数中写数值。\n4、对于任何数值类型的指针(输出参数)一律使用结构体表示,例如double * v 表示为{ double v }\n5、数组使用结构体表示\n6、所有结构体传给API的都是指针地址,都是输出参数并增加返回值\n\n二、返回值规则:\n1、返回值默认为int类型,可用 >>> 0 强制转为无符号数,\n2、可以使用[API尾标]改变返回值为其他类型\n\n三、所有可用的【API尾标】:\ndll.ApiNameW() 切换到Unicode版本,字符串UTF8-UTF16双向转换\ndll.ApiNameA() 切换到ANSI版本,字符串不作任何转换\ndll.ApiNameL() 返回值为 math.size64 对象(64位无符号 LONG 类型)\ndll.ApiNameP() 返回值为指针类型\ndll.ApiNameD() 返回值为double浮点数\ndll.ApiNameF() 返回值为float浮点数\ndll.ApiNameB() 返回值为C++中的8位bool类型\n注意尾标必须大写且尾标前没有大写字符,\nAPI 已含W尾标时可省略,API以'_w'结尾也按 Unicode 版本处理。 !ioFile.read( = 自文件读取数据。\n支持不定个数参数,每个参数指定一个读取标志并增加一个返回值。\n\n参数为"%s"读取并返回一行,参数数为 "%d" 读取一个数值。\n参数为数值则读取指定字节长度的数据并返回字符串。\n参数为结构体则读取数据并填充结构体的值。\n\n函数执行失败返回 null,错误信息,错误代码。 !ioFile.read(.() = 从当前位置,向后读取下一行。\n失败返回 null,错误信息,错误代码。 !ioFile.read(.("%s") = 从当前位置,向后读取下一行,支持多参数。\n失败返回 null,错误信息,错误代码。 !ioFile.read(.("%d") = 从当前位置,向后读取下一个数值,支持多参数。\n失败返回 null,错误信息,错误代码。 !ioFile.read(.(-1) = 向后读取到文件尾部。\n参数为负数表示读取到从文件尾部倒计数位置,支持多参数。\n成功返回读取数据,失败返回 null,错误信息,错误代码。\n读取普通文件全部数据使用 string.load 或 string.loadBuffer 更方便。 !ioFile.readAll() = 移动指针到文件头,\n读取到文件尾返回全部数据。\n改用 -1 为参数调用 read 函数可自当前位置读取到文件尾。\n简单读取普通文件全部数据使用 string.load 或 string.loadBuffer 更方便 !ioFile.read(.(0) = 检测是否未读取到文件尾。\n如果未到文件尾返回空字符串,已到文件尾则返回 null。\n注意在布尔表达式中空字符串等于 true,null 等于 false。 !ioFile.readUtf16(.(读取字符数) = 读取 UTF-16 编码数据,如果文件头有 BOM 会自动移除,\n参数按字符计数,不是按字节计数,\n如果已到文件尾读取长度可能小于参数指定的长度 !ioFile.readUtf16(.(读取字符数,true) = 读取 UTF-16 编码数据,并直接返回 UTF-16 编码的字符串,\n参数按字符计数,不是按字节计数 !ioFile.readBuffer( = 读取数据到 buffer,成功返回读取长度,失败返回null !ioFile.readBuffer(.(buffer指针,读取长度) = 直接读数据到内存,\n参数 @1 可以是 buffer,或内存指针。\n如果参数 @1 是指针则必须指定读取长度,否则可选是否指定长度参数。\n成功返回读取长度。 !ioFile.writeBuffer( = 写入buffer数据,成功返回写入长度,失败返回 null !ioFile.writeBuffer(.(buffer指针,写入长度) = 直接写数据到内存。\n参数 @1 可以是 buffer、字符串、内存指针,\n如果是指针则必须指定写入长度,否则长度参数可选。\n成功返回写入长度。 !ioFile.write( = 写数据 !ioFile.write(.(__, ) = 写数据,可指定一个或多个参数。\n所有参数都支持字符串、buffer、数值、结构体等类型。\n成功返回 true,失败返回 null,错误信息,错误代码 !ioFile.readTo(__) = 读取到指定结束字符前面的所有字符,\n\n参数@1指定结束字符的字节码(数值),\n单引号包含字符并加#号取字节码,例如 '\0'#\n如果没有指定参数,则参数默认为'\0'#\n\n返回字符串不包含结束字符,但文件指针会移到该字符后面,\n如果未遇到指定字符,则读取到文件尾 !ioFile.readback() = 从当前位置,向前读取上一行\n仅支持UTF8或ANSI换行符,不支持UTF16换行符 !ioFile.readback(-1) = 向前读取到文件头部\n负数表示从文件头部倒计数位置 !ioFile.readback(0) = 检测是否读取到文件头 !ioFile.readback(__) = 正数参数表示从当前位置向前读取n个字节 !ioFile.seteof() = 将当前文件位置设为文件末尾,\n用于快速改变文件大小\n成功返回true !ioFile.size64() = 返回文件总大小,返回值为 math.size64 对象。\n此函数不会改变文件指针当前位置。\nsize 函数可以表示的大小为 8PB,一般没有必要使用 size64 函数。\n!math_size64. !ioFile.size() = 返回文件总大小,返回值为普通数值。\n该函数不会改变文件指针当前位置,\n此函数不需要指定任何参数。\nsize 函数可以表示的大小为 8PB,一般没有必要使用 size64 函数。 !ioFile.seek("end") = 移动指针至结束处,并返回文件长度\n获取文件大小推荐使用 size() 函数 !ioFile.seek("end",__) = 移动至相对结束处的指定偏移量,\n偏移量应当是一个普通数值。\n成功返回当前位置(相对于文件开始计数),\n失败返回 null,错误信息,错误代码。注意超越文件尾是允许的 !ioFile.seek() = 得到当前位置(相对于文件开始计数) !ioFile.seek("cur",__) = 移动至相对当前位置的指定偏移量,偏移量应当是一个普通数值。\n1表示向后移动1字节,-1表示向前倒退1字节,\n成功返回当前位置(相对于文件开始计数),\n失败返回null,错误信息,注意超越文件尾是允许的 !ioFile.seek("set") = 移动指针到开始 !ioFile.seek("set",__) = 移动至相对开始处的指定偏移量。\n注意0表示文件开始,1表示第一个字节后面,准备读取的是应该是第2字节,\n成功返回当前位置(相对于文件开始计数),\n失败返回 null,错误信息,错误代码。注意超越文件尾是允许的。\n\n偏移量应当是一个普通数值。\n普通数值的整数上限为 8PB,没有可能会写这么大的文件。\n所以偏移量不支持、也不必要使用 math.size64 对象 !ioFile.reopen("__/*文件路径*/","w+") = 重定向文件流\n成功返回 true,失败返回 null,错误信息,错误代码 !ioFile.reopen("CONOUT$","w__") = 可使用"CONOUT$"重定向到控制台输出缓冲区,\n使用"CONOUT$"重定向到控制台输入缓冲区,\n重定向到控制台只能使用文本模式\n参数@2不可使用ccs标记指定编码\n成功返回 true,失败返回 null,错误信息,错误代码 !ioFile.flush() = 输出缓冲区数据\n成功返回 true,失败返回 null,错误信息,错误代码 !ioFile.close() = 关闭文件流 !ioFile.setvbuf("no") = 禁用缓冲 !ioFile.setvbuf("full",__) = 设为完全缓冲模式,\n读缓冲区直致为空再从流读入数据,写满缓冲区后向流写入数据\n参数@2使用字节数指定缓冲区大小 !ioFile.setvbuf("line",) = 设为行缓冲模式,\n每次从流中读取或写入一行数据\n参数@2使用字节数指定缓冲区大小 !ioFile.mode(.() = 不指定参数时返回表示文件读写模式的数值,\n对于标准输入输出流,aardio在二进制模式不转换编码,在文本模式负责自动转换编码\n\n普通文件对象 aardio 以 UTF8 编码或二进制模式读写,\n不会自动转换文本编码。 !ioFile.mode(.(mode) = 修改文件模式\n参数可设为二进制模式 _O_BINARY 或 文本模式 _O_TEXT,\n\n其他_O_WTEXT,_O_U16TEXT,_O_U8TEXT要求UTF-16读写,\n用于多字节或二进制操作会导致程序异常\n返回表示文件读写模式的数值,\n失败返回 null,错误信息,错误代码。\n指定错误的模式参数时会抛出异常 !ioFile.lines() = @for line in ??.lines(){\n __/*逐行读取文件,循环返回当前行(字符串值)。\n如果以文本模式打开文件,返回文本不含换行符。\n如果以二进制模式打开文件仅移除换行符(不移除回车符),遇'\0'会丢弃后续字符。*/ \n} _O_TEXT=@0x4000/*_O_TEXT*/ _O_BINARY=@0x8000/*_O_BINARY*/ !ioFile.type() = 获取文件对象的类型\n例如控制台,管道,本地文件....等等\n返回值请参考_FILE_TYPE_前缀的常量 io = 文件、文件流相关函数库,\n包含控制台标准输入输出流操作,\n直接操作控制台请使用 console函数库,\n这是自动导入的内置库,\n[使用手册相关文档](doc://library-guide/builtin/io/file.html) io.utf8 = 设为true允许控制台启用UTF8模式\n所有线程设置必须相同,否则会导致重新打开控制台,\nWIN10 以上系统默认值为 true 。\n在 WIN10 以下的系统不建议设为 true,\nconsole 标准库始终使用 unicode 输出文本\nio.stdin,io.stdout,io.stderr 在默认的非二进制模式也使用 unicode 编码 io.popen() = !ioFile. io.lines( = 创建用于 for in 语句的迭代器,逐行读取文件,\n按行拆分普通字符串请使用 string.lines 函数 io.lines(.(文件路径) = 创建用于 for in 语句的迭代器,逐行读取文件\n以文本模式打开文件,遇到`'\x1A'`、`'\0'`终止输入 。\n返回的文本不包含换行 。\n\n循环结束立即关闭此函数打开的文件对象。\n但是:如果使用 break,return 等语句中断循环,\n则打开的文件对象可能不会立即关闭(稍后内存回收后关闭)。\n改为传入文件对象作为参数,可自行控制何时关闭文件 io.lines(.(文件对象) = 创建用于 for in 语句的迭代器,逐行读取文件。\n参数请指定一个用 io.file 打开的文件流对象,等价于调用对象的 lines 成员函数。\n\n如果以文本模式打开文件,返回文本不含换行符,\n如果以二进制模式打开文件仅移除换行符(不移除回车符),遇'\0'会丢弃后续字符。\n\n不负责关闭参数传入的文件对象 io.lines(.() = 无参数时逐行读取标准输入(控制台输入) io.popen(命令行,读写模式) = 执行参数 @1 指定的命令,成功返回进程管道对象。\n失败返回 null,错误信息,错误代码。\n\n参数 @1 如果为完整路径且包含空格,应在首尾加上双引号。\n读写模式为 "r" ( 或省略 )返回绑定目标进程输入流的管道对象,\n读写模式为 "w" 返回绑定绑定目标进程输出流的管道对象。\n\n此函数不隐藏目标程序控制台,建议提前打开控制台。\n建议改用更强大的 process.popen(支持隐藏控制台) io.createDir("/__") = 创建目录\n如果有多个参数则首先用io.joinpath拼接\n如果父目录尚未创建将自动创建\n成功返回完整路径,失败返回空值 io.joinpath( = 用于拼接多个文件路径。\n此函数可以避免文件路径首尾连接处缺少、或多余反斜杠的问题。 io.joinpath(.(dir,->->->) = 用于拼接多个文件路径参数。\n此函数首先会将斜杠自动转换为反斜杠。\n如果连接的非空路径之间没有至少一个反斜杠,则添加反斜杠。\n如果连接处双方都有反斜杠,则去掉其中一个。\n\n也可用参数 @1 指定目录参数,\n然后参数 @2 指定一个要按上述规则追加到尾部的反斜杠。 io.file( = 打开文件,成功返回文件对象,\n失败返回 null,错误信息,错误代码。\n\n此函数创建的文件对象作为调用原生 API 的参数时\n可自动转换为系统文件句柄(存为指针类型)。 io.file(.("/文件路径","读写模式",共享模式) = 参数@1指定路径,\n路径首字符可用斜杠表示应用程序根目录,用~加斜杠表示EXE根目录。\n如果`~\`或`~/`开头的EXE根目录路径不存在,自动转换为应用程序根目录下的路径重试。\n\n参数@2指定打开文件的读写模式,支持以下选项:\nw+ 可读写模式,创建新文件清空源文件\nw 只写模式,清空原文件\nr+ 可读写模式,文件必须存在,不清空文件内容\nr 只读模式,文件必须存在\na+ 可读写追加模式,可打开原文件移动指针到文件尾,也可创建新文件\na 只写追加模式,可打开原文件移动指针到文件尾,也可创建新文件\nb二进制模式,不转换回车换行\nt文本模式,输入使用单换行,输出使用回车换行,遇到 `'\x1A'`或 `'\0'`字符终止输入\nR 随机优化 S 连续优化\nD 创建临时文件,关闭对象后删除文件\n注意: r,w,a只能且必须选择其中一个作为读写模式的第一个字符\n\n参数@3 可选以 _SH_前缀常量指定共享模式 io.file(.(系统文件句柄,读写模式) = 系统文件句柄转换为文件对象\n读写模式为字符串,同样使用"r","w","b"等标记\n必须与原来的文件句柄使用相同的模式 io.file(.() = 第一个参数为 null 或 空字符串时创建并返回临时文件 io.file() = !ioFile. io.open() = 此函数用于打开控制台。\n除可选用参数 @2 自定义控制台标题(参数 @1 必须为 null 值),不可指定任何其他参数。\n改用基于 io.open 的 console.open 打开控制台可提供更多功能:\n- console 的很多库函数可自动按需调用 console.open\n- console.open 不会像 io.open 那样重置控制台并清除之前输出的内容\n- console.open 将更好地设置的控制台选项\n- console.open 会自动重定向 msvcrt.dll 的标准输入输出流\n- console.open 发布 afterConsoleOpen 消息,\n 其他库可响应该消息并自动重定向标准输入输出到控制台。\n!!ioFile. io.close() = 关闭控制台窗口。\n程序退出也会自动关闭控制台窗口。\n 调用 execute("pause") 或 console.pause() 可等待用户按键以避免立即退出 io.stdout = 标准输出,\n在二进制模式下不做任何转换,\n但在文本模式下始终以 Unicode 编码输出文本,\n!ioFile. io.stderr = 标准错误输出,\n在二进制模式下不做任何转换,\n但在文本模式下始终以 Unicode 编码输出文本,\n!ioFile. io.stdin = 标准输入,\n在二进制模式下不做任何转换,\n但在文本模式下始终以 Unicode 编码读取返回UTF-8编码文本,\n\n自控制台读取字符时,使用io.getText可以更好的支持Unicode字符\n!ioFile. io._exepath = 主程序文件路径\n返回完整长路径,不会返回8.3短路径,不会返回相对路径 io._exefile = 主程序文件名 io._exedir = 主程序所在目录,\n返回完整长路径,不会返回8.3短路径,不会返回相对路径\n\n目录路径以反斜杠结束 io.localpath("__") = 如果路径使用了 aardio 专用格式转换为系统支持的完整路径,\n否则返回空值。\n\n转换规则如下:\n\n如果路径以双反斜杠 `\\` 开始,不作转换直接返回 null 空值,\n如果路径以双正斜杠 `//` 开始,移除第一个斜杠后返回,不作其他转换,可用于表示系统分区根目录。\n如果以单个 `\` `/` 字符开始,将参数作为 aardio 应用程序根目录下的相对路径转换并返回完整路径。\n如果路径以 `~` 开始,将参数作为当前启动 EXE 根目录下的相对路径转换并返回完整路径。\n其他格式路径不作转换返 null 空值。 io.libpath("__") = 将库路径转换为文件路径;\n如果库存在则返回 2 个值:库文件路径,库文件所在目录\n否则库路径返回null空值,按用户库合法格式返回目录路径,\n返回的库目录路径以反斜杠结束. io.fullpath("__") = 将相对路径转换为绝对路径,转换规则如下:\n\n如果路径以双反斜杠 `\\` 开始,不作转换直接返回,路径前加 `\\?\` 可避免转换并支持畸形路径,\n如果路径以双正斜杠 `//` 开始,移除第一个斜杠后返回,不作其他转换,用于表示系统分区根目录,\n如果以单个 `\` `/` 字符开始,作为 aardio 应用程序根目录下的相对路径转换并返回完整路径,\n如果路径以 `~` 开始,作为当前运行的EXE根目录下的相对路径转换并返回完整路径,\n其他路径按系统规则转换为完整路径,\n传入空字符串或空值返回 null\n\n注意相对路径 `.\` 易被改变,例如打开文件对话框可能改变相对路径。\n而 aardio 提供的应用程序根目录表示确定的位置。 io.rename( = 重命名文件 io.rename(.(from,to) = 将参数 @1 指定路径的文件重命名为参数 @2 指定的文件路径。\n成功返回 true,失败返回 null io.remove("__") = 删除参数 @1 指定路径的文件。\n在路径前加上 `\\?\` 可支持畸形路径。\n成功返回 true,失败返回 null,错误信息,错误代码 。\n\n此函数仅用于删除文件,\n删除目录请改用 fsys.delete、fsys.deleteEx 或 fsys.remove 函数。 io.splitpath(__) = 拆分文件路径为目录、文件名、后缀名、分区号等,\n返回 io.pathInfo 对象,\n返回对象可修改drive,path,name,ext等字段,\n并可作为 tostring 函数的参数重新合成为文件路径 io.print(.(->->->) = 在标准输出流(默认为控制台)输出信息。\n可指定任意个参数,参数自动调用 tostring 函数转为字符串。\n多参数输出时自动以制表符分开,最后会输出一个换行。 io.print( = 在标准输出流(默认为控制台)输出信息。\n此函数没有自动打开控制台的功能。\n改用 print,console.log 函数可自动打开控制台窗口。 io.exist( = 判断文件路径是否存在,\n也可以用于判断文件是否可读写。\n\n包含不可见字符的错误路径可用「工具>文本文件>十六进制编辑器」\n或 string.hex 函数查看 io.exist(.("文件路径") = 判断文件路径是否存在\n存在则转换为绝对路径并返回该路径,不存在返回null\n参数@1不是有效字符串返回null io.exist(.("文件路径",2) = 测试文件是否可写\n成功则转换为绝对路径并返回该路径,失败返回null\n目录或只读文件直接返回null\n参数@1不是有效字符串返回null io.exist(.("文件路径",4) = 测试文件是否可读\n成功则转换为绝对路径并返回该路径,失败返回null\n目录返回null\n参数@1不是有效字符串返回null io.exist(.("文件路径",6) = 判断文件是否可读写\n成功则转换为绝对路径并返回该路径,失败返回null\n目录返回null\n参数@1不是有效字符串返回null io.getText(__/*可选指定缓冲区大小*/) = 读取控制台文本\n不包含尾部的回车换行,\n相比使用io.stdin.read函数,io.getText 可更好的支持 Unicode 字符 !ioSplitFileInfo.dir = 目录路径(含盘符),\n此属性 由path,drive 属性动态合成,\n只供读取,不应直接赋值 !ioSplitFileInfo.path = 目录路径(不含盘符)\n此路径首尾都必须是反斜杠 !ioSplitFileInfo.file = 文件名(含后缀)\n此属性由 name,ext 属性动态合成,\n只供读取,不应直接赋值 !ioSplitFileInfo.name = 文件名(不含后缀) !ioSplitFileInfo.ext = 文件后缀名\n包含后缀名前面的圆点,例如".aardio" !ioSplitFileInfo.drive = 文件所在分区,\n盘符可为空,非空则以冒号结束,\n不应包含反斜杠 io.splitpath() = !ioSplitFileInfo. math.size64( = 创建无符号 64 位无符号正整数(cdata 类型对象)。\n参数可输入 10 进制数值,或 0x,0X 前缀的 16 进制数值。\n返回对象可使用 tostring 函数转换为字符串,可用 tonumber 函数转换为 64 位浮点数,\n\n2 个同类型的 math.size64 对象作为操作数可支持大于,小于,等于等关系运算符。\nmath.size64 对象可与普通数值进行 `+,-,*,/` 等运算。\n操作数为 math.size64 对时使用除运算符 `/` 返回浮点数值,使用其他算术运算返回 math.size64 对象。\n\n1、API函数返回值中 LONG 类型返回为 math.size64 对象。\nmath.size64 对象也支持连接操作符(自动将左右操作数转为字符串)。\n2、在API回调函数中,LONG类型回调参数为 math.size64 对象\n3、结构体中LONG类型,API函数的LONG&&类型,实际赋值为math.size64对象时,\n则始终保持该对象类型及地址不变,反之则处理为64位浮点数值\n\n64位浮点数值表示的有效整数在正负 (2**53 - 1) 之间,\n可以表示8PB文件长度,只有必须用到64位全部字节表示整数时,\n才有必要使用math.size64对象. math.size64(.("数值") = 参数使用字符串指定无符号 64 位正整数。\n参数可指定 10 进制数值或 0x 前缀的 16 进制数值。\n参数不支持自定义进制与下划线分隔符,忽略开始的空白字符,忽略有效数值后的多余字符。\n省略参数或字符串参数未指定有效数值时初始化为 0 。\n\naardio中普通数值存储为 64 位浮点数,可表示的有效整数为正负 `2**53-1` 之间。\nmath.size64 则能表示更大的正整数。 math.size64(.(低32位,高32位) = 创建并返回size64对象,\n参数使用两个32位数值指定无符号64位正整数,\n使用此64位整数创建并返回size64对象 math.size64(.(math->size64对象) = 复制无符号64位正整数,\n使用此64位整数创建并返回size64对象 math.size64(.(结构体) = 参数须传入不小于64位的结构体,\n将结构体内存转换为64位无符号整数,\n使用此64位整数创建并返回size64对象 math.size64() = !math_size64. !math_size64.lessThan(__) = 判断是否小于指定的数值,\n参数可以是普通正负数值,也可以是math.size64对象\n注意math.size64对象不能直接用`<`,`<=`与普通数值进行比较 !math_size64.greaterThan(__) = 判断是否大于指定的数值,\n参数可以是普通正负数值,也可以是math.size64对象\n注意math.size64对象不能直接用`>`,`>=`与普通数值进行比较 !math_size64.reset(.(低32位,高32位) = 重新设置值\n支持构造math.size64的所有构造参数 !math_size64.format() = 转换字节长度到适合的最大单位表示的文本,\n单位使用 bytes,KB,MB,GB等 !math_size64.add(.(数值) = 加法运算,函数修改并返回自身,\n使用+运算符替代此函数可返回新值不改变自身\n参数可以是math.size64对象,\n或者是普通数值,允许使用负数 !math_size64.sub(.(数值) = 减法运算,函数修改并返回自身,\n使用-运算符替代此函数可返回新值不改变自身\n参数可以是math.size64对象,\n或者是普通正整数 !math_size64.mul(.(数值) = 乘法运算,函数修改并返回自身,\n使用*运算符替代此函数可返回新值不改变自身\n参数可以是math.size64对象,\n或者是普通正整数 !math_size64.div(.(数值) = 除法运算,函数修改并返回自身。\n参数可以是 math.size64 对象,\n或者是普通正整数,注意运算结果不是浮点数。\n\nmath.size64 对象的除法运算符使用 divf 而不是 div 函数运算 !math_size64.divf(.(数值) = 除法运算,返回普通浮点数值。\n此函数不修改对象自身而是返回一个普通数值。\nmath.size64 对象的除法运算符使用此函数运算 !math_size64.mod(.(数值) = 取模运算,函数修改并返回自身,\n使用%运算符替代此函数可返回新值不改变自身\n参数可以是math.size64对象,\n或者是普通正整数 !math_size64.lshift(.(数值) = 按位左移,函数修改并返回自身,\n使用`<<`运算符替代此函数可返回新值不改变自身\n参数只能是普通正整数 !math_size64.rshift(.(数值) = 按位右移,函数修改并返回自身,\n使用`>>`运算符替代此函数可返回新值不改变自身\n参数只能是普通正整数 !math_size64.split32() = 返回低32位,高32位数值 !math_size64.swap() = 大小端字节序反向转换 !math_size64.add() = !math_size64. !math_size64.sub() = !math_size64. !math_size64.mul() = !math_size64. !math_size64.div() = !math_size64. !math_size64.mod() = !math_size64. math.ceil(__/*输入数值*/) = 上取整为最接近的整数,\n正无穷大方向取相邻的整数,\n下取整请使用 math.floor 函数,\n四舍五入请使用 math.round 函数 math.floor(__/*输入数值*/) = 下取整为最接近的整数,\n负无穷大方向取相邻的整数,\n上取整请使用 math.ceil 函数,\n四舍五入请使用 math.round 函数 math.abs(__/*输入数值*/) = 计算绝对值 math.acos(__/*输入数值*/) = 计算反余弦值 math.asin(__/*输入数值*/) = 计算反正弦值 math.atan(__/*输入数值*/) = 计算反正切值 math.atan2(.(x__,y) = x/y的反正切值 math.cos(__/*输入数值*/) = 计算余弦值 math.deg(__/*输入弧度*/)= 弧度转换为角度 math.exp(__/*输入数值*/) = 计算以e为底x次方值 math.cosh(__/*输入数值*/) = 双曲线余弦函数 math.frexp(__/*输入数值*/) = 把双精度数val分解为数字部分(尾数)和以2为底的指数n,即val=x*2n math.ldexp(.(value__,n) = 计算value * 2的n次方 math.log10(__/*输入数值*/)= 计算以10为基数的对数 math.log(__/*输入数值*/) = 计算自然对数 math.max(__/*输入数值*/, ) = 返回多个数值中较大的一个。\n可输入 2 个以上的参数 math.min(__/*输入数值*/, ) = 返回多个数值中较小的一个。\n可输入 2 个以上的参数 math.random( = 返回随机数。\n生成随机字符串请使用 string.random 函数。\n生成安全随机数请使用 crypt.random 库。 math.random(.() = 返回 0 到 1 之间的随机数(小数),\n可用乘法与 math.round 函数转为整数 math.random(.(max) = 返回从 1 到 max 范围的随机整数,参数必须是整数,\n可以利用除法将返回值转换为小数 math.random(.(min,max) = 返回从 min 到 max 范围的随机整数,参数必须是 2 个整数,\n可以利用除法将返回值转换为小数。\n此函数传入字符串会自动转换为数值。 math.randomize() = 设置随机数发生器的种子。\n参数可以指定任意数值,省略则自动生成一个随机数作为随机数种子。\n所有线程启动时都会自动生成一个安全的随机数作为随机数种子。\n\n[使用手册相关文档](doc://library-guide/builtin/string/rand.md) math.modf(__/*输入数值*/) = 把数拆分为整数、小数。\n返回两个值。 math.rad(__/*输入角度*/) = 角度转换为弧度 math.sinh(__/*输入数值*/) = 正弦值(角度) math.sin(__/*输入数值*/) = 计算正弦值 math.sqrt(__/*输入数值*/) = 计算平方根( √x ) math.tanh(__/*输入数值*/) = 计算正切值(角度) math.tan(__/*输入数值*/) = 计算正切值 math.pi = 圆周与直径的比值常数( π ) math = 数学计算库\n这是自动导入的内置库 time = 日期时间,这是自动导入的内核类库,\n字符串格式化支持从 1900 年 1 月 1 日 到 9999 年 12 月 31 日 的时间\n可用 tonumber 转换为自 UTC 时间 1970 年 1 月 1 日 00:00:00 到 3000 年 12 月 31 日 23:59:59 间的秒数\n需要更宽的运算范围请使用继承自 time 的 time.ole 类库。\n\n[time 库使用指南](doc://library-guide/builtin/time/time.md) time.now( = 获取当前时间并返回 time 对象。\n在 milliseconds 字段返回毫秒数,且 dayofyear 字段无效 time.now(.(format,local) = 取当前时间并返回 time 对象,等价于省略第一个参数调用 time 构造函数。\n在 milliseconds 字段返回毫秒数,且 dayofyear 字段无效。\n所有参数为可选参数。\n\n可选用参数 @format 指定格式化串,首字符为 `!` 表示 UTC 时间。\n省略格式串时默认值为 `%Y/%m/%d %H:%M:%S`,可兼容解析 ISO8601 格式时间。\n创建对象后可通过 format 属性单独修改输出时间格式。\n\n可选用参数 @local 指定对象的 locale 属性,即格式化时间使用的区域语言。\nlocale 参数支持的区域语言 与 setlocale 函数相同,英文 "enu",中文 "chs" time.format(.(format,local) = 取当前时间并返回格式化后的字符串。\n所有参数可选,参数用法请参考 time 构造函数与 time 库使用指南。\n格式化串使用百分号风格,例如:"!%Y年%m月%d日 %H时%M分%S秒"。\n兼容不带百分号风格的时间格式串,例如 "!yyyy-mm-dd HH:MM:SS"(Y D S 忽略大小写)。\nlocale 参数支持的区域语言 与 setlocale 函数相同,英文 "enu",中文 "chs" time.format(.(timeObject,format,local) = 格式化 timeObject 参数指定的 time 或 time.ole 对象,并返回字符串。\n所有参数可选,参数用法请参考 time 构造函数与 time 库使用指南。\n提供这个函数只是因为命名的原因比较好找到,改用 tostring 可支持以与这里相同的参数用法格式化时间,还可以少打几个字符。\n也可以直接调用 timeObject.format 方法,作用相同。 time.stamp( = 取 Unix 时间戳。\n时间戳 0 表示 ISO8601 时间 1970-01-01T00:00:00Z time.stamp(.(是否返回字符串,是否以秒为单位) = 所有参数可省略。\n默认返回以毫秒为单位的时间戳数值,。\n参数 @1 为 true 则返回文本,否则返回数值。\n参数 @2 指定为 true 则返回值以秒为单位,否则以毫秒为单位。 time.tick() = 获取系统启动时间,单位毫秒。\nXP 系统每 49.7 天重置为 0,之后的系统无此限制。\n高精度高性能计时请参考 time.performance.tick 函数。 time.istime(__) = 判断对象是否与 time 对象兼容的结构体。\n传入 time,time.ole 对象会返回 true。\n此函数仅检测结构体的类型声明不考虑对象的元表指向。 time( = 创建时间对象,返回对象可传入其他线程使用,\n\n时间对象可作为调用 tonumber 的参数转换为\n自UTC时间1970年1月1日 00:00:00 到 3000年12月31日23:59:59 之间的秒数\n\n也可以作为调用tostring函数的参数转换为字符串 time(.() = 获取当前时间。\n不指定参数、或者格式化以前都是默认初始化为当前时间。\n\n不指定参数@1 在 milliseconds 字段返回毫秒数,且 dayofyear 字段无效,\n参数@1指定其他参数时 milliseconds 字段总是为 0 time(.(__,"%Y/%m/%d %H:%M:%S") = 构造并返回时间对象。\n参数 @1 可指定表示时间的数值、字符串或需要复制的 time、time.ole 对象。\n也以在参数 @1 指定指定包含部分时间对象字段的参数表,不指定参数 @1 则初始化为当前时间。\n\n可选用参数 @2 指定格式化串,首字符为 `!` 表示 UTC 时间。\n格式化串可用于自文本解析时间,也可将时间格式化为文本。\n也可修改返回时间对象的 format 属性以单独变更输出格式。\n省略格式串时则默认设为 `%Y/%m/%d %H:%M:%S`,可兼容解析 ISO8601 格式的时间。\n\n参数@1 为文本时,则依据参数 @2 指定的格式化串解析时间。\n自文本解析时间使用尽可能宽松的规则,格式串中非 `%` 前导的字符、分隔符都不要求精确匹配。\n兼容宽松的无百分号风格格式化串(自动转为百分号格式),例如 "yyyy-mm-dd HH:MM:SS"。\n如果输入文本中的时间数值超出日期范围,或者输入文本提前结束,都会返回 null 。\n如果出现当月不存在的日期且小于 31 号时会顺推为下月时间。\n\n可选用参数 @local 指定对象的 locale 属性,即格式化时间使用的区域语言。\nlocale 支持的区域语言 与 setlocale 函数相同,英文 "enu",中文 "chs"。 time.iso8601(__) = 返回 ISO8601 格式 GMT 时间。\n参数可以是数值,字符串,或其他time对象,用法参考time构造函数,\n如果参数是使用本地时间的 time 对象,返回补偿时差后的标准时间。\n\n如果参数是字符串,可支持 ISO8601 省略分隔符的写法。支持仅日期无时间的格式。\n但日期必须包含年月日,时间必须包含时分秒,不能只写那部分。\n字符串中如果使用数值格式指定了时区,将自动补偿时差转换为 GMT 时区\n时区以正负号开始,支持省略冒号分隔符的1位,2位,3位,4位数字缩写 time.gmt(__) = 返回 RFC1123 格式 GMT 时间,HTTP 协议使用该格式。\n参数可以是数值,字符串,或其他time对象,用法参考time构造函数,\n如果参数是使用本地时间的 time 对象,返回补偿时后的标准时间。\n如果参数是字符串,可兼容解析 RFC 850,RFC1123 两种格式,\n例如:"Sun, 07 Feb 2016 01:11:22 GMT",\n字符串中如果使用数值格式指定了时区,将自动补偿时差转换为 GMT 时区\n时区以正负号开始,支持省略冒号分隔符的1位,2位,3位,4位数字缩写 time.utc(__) = 返回 UTC 标准时间。\ntime.gmt,time.utc 返回相同的 UTC 时间,区别仅仅是默认格式化串不同。\n参数可以是数值,字符串,或其他time对象,用法参考 time 构造函数,\n如果参数是使用本地时间的 time 对象,返回补偿时后的标准时间。\n格式化串默认指定为 "!%Y/%m/%d %H:%M:%S" \n如果参数是字符串,解析失败则尝试修改格式化串为 "!%Y/%m/%d" 解析。\n可兼容解析 ISO8601 格式(可省略分隔符)。 time.gmt() = !time. time.iso8601() = !time. time.utc() = !time. !time = class datetime{\nWORD year; //年\nWORD month; //月\nWORD dayofweek; //星期\nWORD day; //日期\nWORD hour; //小时\nWORD minute; //分钟\nWORD second; //秒\nWORD milliseconds; //这个字段正常情况下为0,只有在WINAPI函数中会起作用\nformat; //时间格式字符串\nisdst //是否夏令时\n} !time.year = 年 !time.dayofweek = 星期\n星期一到星期六的值对应数值为1到6,星期日的值为 0,\n注意修改这个字段不会更新时间值,\n\n这个字段只有参与数值运算或调用 add*** 函数才会填充或更新,\n例如调用 addday(0) 会更新此字段 !time.dayofyear = 所在年份的天数,\n注意修改这个字段不会更新时间值。\n无参数调用 time 或 time.now 函数此字段无效。\n\n这个字段只有参与数值运算或调用 add*** 函数才会填充或更新,\n例如调用addsecond(0)会更新此字段,\n\n使用格式化标记%j %U %W前必须首先刷新此字段 !time.day = 日 !time.month= 月 !time.hour= 小时 !time.minute= 分钟 !time.second= 秒 !time.milliseconds = 毫秒。\n构造 time 对象不指定参数 @1 或用 time.now 取当前时间,则设置此字段为当前毫秒数,否则此字段无效 !time.endstr = 文本解析为时间后,\n最后一个格式化标记解析成功并跳过空白字符以后的剩余字符串。 !time.locale = 格式化时间使用的语言代码\n参数与setlocale相同,英文"enu",中文"chs",\n该属性为空表示使用当前默认语言 !time.format = 作为属性可读写默认格式化串,首字符为`!`表示 UTC 时间。\n例如:"!%Y年%m月%d日 %H时%M分%S秒"。\n兼容不带百分号风格的时间格式串,例如 "!yyyy-mm-dd HH:MM:SS"(Y D S 忽略大小写)。\n关于格式化串详细说明请查看 time 库文档。\n参数 @2 setlocale 函数支持相同的区域语言代码,例如:英文"enu",中文"chs" !time.format(.(格式化串,区域代码) = 作为方法调用( owner.call 方式 )时可格式化时间并返回字符串。\n所有参数可选,格式化串兼容百分号与无百分号风格,示例:\n "%Y年%m月%d日 %H时%M分%S秒" 或 "yyyy-mm-dd HH:MM:SS" 。\n关于格式化串详细说明请查看 time 库使用指南。 !time.local() = 将 UTC 时间转换为本地时间,修改并返回对象自身。\n如果已经是本地时间则直接返回对象自身。\n对象的格式化串(format 属性)首字符为`!`表示 UTC 时间。\n!time. !time.local(true) = 将 UTC 时间转换为本地时间。\n参数为 true 则不修改自身而是返回新对象。\n如果已经是本地时间则直接复制并返回复制的新对象。 !time.utc() = 将本地时间转换为 UTC 时间,修改并返回对象自身。\n如果已经是 UTC 时间直接返回。\n\n对象的格式化串(format 属性)首字符为`!`表示UTF时间。\n!time. !time.utc(true) = 将本地时间转换为 UTC 时间。\n参数为 true 则不修改自身而是返回新对象。\n如果已经是 UTC 时间则复制并返回复制的新对象。 !time.update() = 重新计算时间并更新dayOfWeek字段.\n!time. !time.addmonth(__/*输入数值*/) = 增加月份数,返回自身 !time.addday(__/*输入数值*/) = 增加天数,可以为负数,返回自身 !time.addsecond(__/*输入数值*/) = 增加秒数,可以为负数,返回自身 !time.addminute(__/*输入数值*/) = 增加分钟数,可以为负数,返回自身 !time.addhour(__/*输入数值*/) = 增加小时数,可以为负数,返回自身 !time.addmonth() = !time. !time.addday() = !time. !time.addsecond() = !time. !time.addminute() = !time. !time.addhour() = !time. !time.diffmonth(__/*指定time对象*/) = 用当前time对象减参数指定的time对象\n计算两个time对象相差月份 !time.diffday(__/*指定time对象*/) = 用当前time对象减参数指定的time对象\n计算两个time对象相差天数 !time.diffsecond(__/*指定time对象*/) = 用当前time对象减参数指定的time对象\n计算两个time对象相差秒数 !time.diffminute(__/*指定time对象*/) = 用当前time对象减参数指定的time对象\n计算两个time对象相差分钟数 !time.diffhour(__/*指定time对象*/) = 用当前time对象减参数指定的time对象\n计算两个time对象相差小时数 !time.getMilliTime() = 返回自UTC时间 1970年1月1日 00:00:00 开始的毫秒数\n最大值为UTC时间3000年12月31日23:59:59 !time.setMilliTime(__) = 参数为数值\n设置自UTC时间 1970年1月1日 00:00:00 开始的毫秒数\n最大值为UTC时间3000年12月31日23:59:59\n此函数返回时间对象自身 !time.setMilliTime() = !time. time() = !time. time.now() = !time. thread.callWnd(.(hwnd,"成员函数名",->->-> ) = 调用UI线程窗体对象的成员函数\n调用同一线程中的目标窗口函数时,此函数忽略不操作\n参数@1必须指定win.form对象的hwnd句柄\n参数@2指定要调用的成员函数名,支持get元方法ownerCall特性\n可添加不定个数的调用参数 thread.getWnd(.(hwnd,"属性名") = 获取UI线程窗体对象的属性,\n调用同一线程中的目标窗口函数时,此函数忽略不操作 thread.setWnd(.(hwnd,"属性名",属性值) = 设置UI线程窗体对象的属性,\n调用同一线程中的目标窗口函数时,此函数忽略不操作 thread.applyCallWnd(this,wParam,lParam) = 在窗口_WM_THREAD_CALLWND消息回调中响应:\nthread.callWnd,thread.getWnd thread.setWnd调用\nwin.form对象默认已应用此函数 thread.call(.("函数","owner", ) = 在线程安全模式下执行线程共享区函数\n可以指定一个线程函数,或者用thread.set预加载到共享区的函数名,\n可增加任意个调用参数 thread.getMainId() = 返回启动当前进程的主线程 ID。\n\n在开发环境内以线程模式运行 aardio 代码时返回 IDE 主线程。\n\n默认情况下 aardio 总是在 IDE 进程外运行 aardio 代码,\n除非在 IDE 插件中调用 ide.createThread 在 IDE 线程内启动 aardio 代码。\n任何时候都应当避免使用 ide.createThread 并改用 ide.createProcess 替代。 thread.main() = 当前线程是否 主线程。 thread.getId() = 返回当前线程ID。\n将线程句柄转换为线程 ID 请使用 ::Kernel32.GetThreadId 函数。 thread.open( = 传入线程 ID 并返回打开的线程句柄。\n将线程句柄转换为线程 ID 请使用 ::Kernel32.GetThreadId 函数。 thread.open(.(线程ID,权限,句柄是否可继承) = 打开线程句柄,失败请使用 ..lasterr() 获取错误信息.\n参数二可省略,默认为_THREAD_ALL_ACCESS\n参数三默认为false\n返回的句柄必须使用 raw.closehandle()关闭 thread.getHandle() = 返回当前线程伪句柄\n该句柄仅可在当前线程使用、可复制 thread.create(.(线程函数,调用参数) = @\n function( ... ){\n import win; //线程需要独立引用库\n \n \n },\n __/*传入线程函数的实参写到这里\n线程函数的 owner 参数总是为空*/\n) thread.create(.(aardio文件路径,调用参数) = 创建线程运行 *.aardio 文件,\n该文件所在目录将被设定为此线程的应用程序根目录,\n该目录下的"/lib/"目录将被设定为用户库目录,\n在线程文件内可使用owner参数获取这里传入的首个调用参数 thread.create( = 创建线程,返回句柄、线程ID\n线程句柄不再使用时,应调用raw.closehandle 函数关闭。\n第一个参数是启动线程的函数,其余参数传递给线程函数。\n\n注意线程函数有独立的全局变量环境,线程引用的库应当在线程函数内 import thread.stop(__/*退出代码*/) = 终止当前线程。 thread.set( = 写入一个线程共享数据到进程共享内存区。 thread.set(.(uniqueKey,value) = \n参数 @uniqueKey 可以是数值、字符串或 pointer 类型指针,\n@uniqueKey 是线程共享数据的唯一性标识。\n\n参数 @value 指定线程共享数据的值(必须遵守线程间传递数据的规则)。\n赋值为 null 则删除指定的线程共享数据。\n\n禁止在任何元方法中使用此函数。 thread.get( = 从进程共享内存区读取线程共享数据。 thread.get(.(uniqueKey) = n参数 @uniqueKey 可以是数值、字符串或 pointer 类型指针,\n@uniqueKey 是线程共享数据的唯一性标识。\n\n禁止在任何元方法中使用此函数。 thread.lock("临界区名称") = 请求锁定并进入临界区\n一个线程进入指定名字临界区,其他线程必须等待,\n直到当前进入临界区的代码调用thread.unlock解锁 thread.lock("临界区名称",执行函数) = @.lock("临界区名称",function(){\n __/*退出函数自动解锁临界区,返回此函数的返回值*/\n}) thread.unlock("临界区名称") = 解锁释放当前占用的临界区,\n调用thread.lock且指定了执行函数时不需要调用此函数解锁 thread.unlock() = 解锁\n等效于thread.unlock("default") thread.terminate(__/*线程句柄*/,0) = 强制终制线程,不推荐使用\n参数二设定返回值,可通过thread.getExitCode获取。 thread.resume(__/*线程句柄*/) = 继续执行 thread.suspend(__/*线程句柄*/) = 暂停执行\n注意线程是否正在使用互斥锁 thread.getExitCode(__/*线程句柄*/) = 获取线程函数返回代码 thread.tofastcall(.(函数对象,"int()",owner) = 创建多线程回调函数,使用 ms-fastcall 调用约定\n回调线程不是当前线程应使用此函数替换 raw.tostdcall\n回调函数使用独立的线程环境,所有 import 语句必须放在函数体内部\n回调函数在同一线程触发时将复用已创建的线程环境\n可选用参数@3指定回调 owner 参数,该参数必须符合跨线程传递规则\n如果在回调线程内未调用 thread.callbackInitialize,则不能使用 COM 对象\n\n其他参数、返回值规则与 raw 命名空间下同名函数相同 thread.tostdcall(.(函数对象,"int()",owner) = 创建多线程回调函数,使用 stdcall 调用约定\n回调线程不是当前线程应使用此函数替换 raw.tostdcall\n回调函数使用独立的线程环境,所有 import 语句必须放在函数体内部\n回调函数在同一线程触发时将复用已创建的线程环境\n可选用参数@3指定回调 owner 参数,该参数必须符合跨线程传递规则\n如果在回调线程内未调用 thread.callbackInitialize,则不能使用 COM 对象\n\n其他参数、返回值规则与 raw 命名空间下同名函数相同 thread.tocdecl(.(函数对象,"int()",owner) = 创建多线程回调函数,使用 cdecl 调用约定\n回调线程不是当前线程应使用此函数替换 raw.tocdecl\n回调函数使用独立的线程环境,所有 import 语句必须放在函数体内部\n回调函数在同一线程触发时将复用已创建的线程环境\n可选用参数@3指定回调 owner 参数,该参数必须符合跨线程传递规则\n如果在回调线程内未调用 thread.callbackInitialize,则不能使用 COM 对象\n\n其他参数、返回值规则与 raw 命名空间下同名函数相同 thread.callbackInitialize() = 初始化COM套间\n调用此函数以后,创建线程的外部组件应在线程退出前回调 thread.callbackUninitialize\n\n此函数只能用于:\nthread.tocdecl,tostdcall,tofastcall 等创建的多线程原生回调函数,\n并且只会在第一次成功执行时返回 true,多次调用忽略不执行并返回 null 空值 thread.callbackUninitialize = 原生回调函数指针,\n函数原型为 void __stdcall callbackUninitialize(DWORD dwThreadId),\n\n如果dwThreadId参数不是当前线程ID,此函数忽略不执行,\n否则aardio执行一系列资源释放操作,如果之前调用了thread.callbackInitialize 函数,\n那么此函数会负责释放 COM 套间。\n\n此函数只能用于:\nthread.tocdecl,tostdcall,tofastcall 等创建的多线程原生回调函数,\n如果线程没有调用过 thread.callbackInitialize,不必要调用此函数\n\n如果没有使用此回调函数释放资源\naardio 将在线程退出后逐渐回收该线程环境 _INVALID_HANDLE_VALUE = topointer(-1)\n表示无效句柄 _HINSTANSE = 当前应用程序的实例句柄 _SH_DENYRW=@0x10/*独占读写*/ _SH_DENYWR=@0x20/*独占写*/ _SH_DENYRD=@0x30/*独占读*/ _SH_DENYNO=@0x40/*共享模式*/ _SH_SECURE=@0x80/*安全模式*/ gcdata(元表) = @..gcdata( \n _topointer = __/*pointer指针*/ \n _gc = function(){\n \n } \n) assert2(2,__) = 断言函数\n参数 @2 为真则返回其他值,否则抛出异常\n参数 @1 指定抛出异常的调用级别,2 为调用者,1 为当前代码 publish("__/*发布消息名*/",) = 在当前线程内发布消息,\n运行当前线程所有所有通过调用 subscribe 函数订阅此消息的函数,\n可添加任意个触发参数 subscribe(订阅消息名,触发函数,是否前置) = @subscribe("__/*要订阅的消息名称, 请使用 publish 函数触发此消息。\n调用 subscribe 函数返回对象的 remove 成员函数可撤消本次订阅。\n在订阅触发函数中返回 false 也可以撤消所属订阅。\n\n如果在触发函数中可能使用已关闭的窗口对象,\n应当先检查窗口的 valid 属性判断窗口是否有效。\n对于这类窗口改用 thread.command 更合适*/",function(...){\n \n} ) subscribe() = !stdSubscriber. !stdSubscriber.remove() = 撤消本次订阅。\n\n如果在需要重复创建的窗体内订阅消息,应在 winform.onDestroy 事件内取消订阅。\n或改用 thread.command 可在窗体关闭后自动取消订阅。\n\n如果只是想调用窗体的成员函数,这本来就可以直接调用,\n不必使用 subscribe fiber.create(.(函数对象,应用程序根目录) = 创建纤程\n调用 fiber.resume 函数启动纤程,\n参数2为可选参数,应用程序根目录只能设置为硬盘上实际存在的目录,\n改变应用程序根目录,会同时改变用户库目录 fiber.resume(__/*纤程函数*/,启动参数->->->) = 继续运行纤程。\n除参数@1以外的其他参数为首次启动纤程函数的调用参数。\n\n成功运行纤程则返回 true 以及纤程内调用 fiber.yield 函数时传入的参数。\n错误则返回 false 以及错误信息. fiber.yield(__/*一个或多个返回值*/) = 暂停纤程,\n此函数传入参数将会作为fiber.resume()的返回值。\n下次调用fiber.resume()的参数即为本次调用的返回值。 fiber.status(__/*纤程*/) = 获取纤程状态 fiber.status.current = 当前正在运行的纤程 fiber.status.running = 正在调用其他纤程 fiber.status.suspended = 等待中 fiber.status.dead = 纤程已完成或已出错 fiber.current() = 返回当前正在运行的纤程\n非纤程内调用则返回null fiber.generator( 生成器,->->-> ) = @for v in fiber.generator(__/*使用纤程创建迭代器。\n参数 @1 指定纤程函数,可添加任意个纤程启动参数。\n纤程函数内使用 fiber.yield 返回迭代值。*/,){\n \n} _struct_aligned = 用于结构体中自定义对齐\n指定为1按按照实际字节数对齐 __messageGet(msg) = 等待并获取窗口消息,\nmsg参数可以是MSG结构体,也可以是一个空表用于接收新的MSG结构体,也可以省略\n成功返回已填充消息的MSG结构体(如果指定了msg参数则该参数就是此返回值),\n失败返回false,程序退出返回null __messagePeek(.(msg,窗口句柄,最小消息,最大消息,选项) = 检查并获取窗口消息,\nmsg参数可以是MSG结构体,也可以是一个空表用于接收新的MSG结构体,也可以省略\n成功返回已填充消息的MSG结构体(如果指定了msg参数则该参数就是此返回值),\n无消息返回false,程序退出返回null\n\n所有参数都是可选参数\n选项不指定则默认为 _PM_REMOVE 表示自消息队列移除该消息\n其他选项请参考同名WINAPI的说明 __messageTranslateDispatch(msg) = 分发处理窗口消息,\n参数为消息对象. win.ui.disableDpiScaling = 在创建窗口前设为 false 则全局禁用 DPI 自动缩放 onError(错误信息,是否已退出退用栈) = @//此函数应在主线程中定义并自动注册到子线程,应遵守线程函数规则\nglobal.onError = function( err,over ){ \n if(!over){\n import debug;\n var stack = debug.traceback(,"调用栈",3);\n }\n \n if( _STUDIO_INVOKED ) return err;__/*IDE中返回错误信息以继续显示*/ \n} print( = aardio 代码在解析模板语法时,将自动调用此函数输出数据。\n在不同类型的应用中,print 可能指向不同的输出函数。\n例如在 HTTP 服务端中 print 将自动指向 response.write 函数。\n而在调用 string.loadcode 时 print 将临时指向拼接字符串的代码。\n\n用户不应随意改动 print 函数的指向,或将 print 赋值到其他变量。\n\n在未加载 aardio 模板代码的默认情况下:\n如果在开发环境中首次调用 print 输出 HTML 则创建网页控件并显示 HTML,\n否则 print 将默认向控制台窗口输出内容(无元表的表或数组序列化后输出,其他参数转字符串输出)。\nprint 在默认调用 io.print 前会自动打开控制台,退出非界面线程前会暂停控制台。 print(.(->->->) = aardio 代码在解析模板语法时,将自动调用此函数输出数据。\n支持多个不定参数,每个参数默认会自动调用 tostring 转换为字符串。\n在不同的模板应用或非模板应用中此函数可能会以不同的方式处理参数。 beforeUnload = @..subscribe("beforeUnload",function(){\n __/*进程的启动线程退出前执行此回调非。\n启动线程可用 table.gc 注册析构函数。*/\n} ); beforeSystemEndSesssion = @..subscribe("beforeSystemEndSesssion",function(){\n __/*即将关机执行此回调,不可执行耗时操作*/\n} ); console = 控制台窗口 coroutine = 协程 crypt = 加密解密 debug = 调试 fsys = 文件操作 gdi = GDI绘图,\n声明了常用绘图WINAPI gdip = GDI+绘图 inet = 网络 key = 键盘模拟 mouse = 鼠标模拟 builtin = 内置库 process = 进程操作,\n[使用手册相关文档](doc://library-guide/std/process/process.html) raw = 原生接口编程与原生类型操作支持库。\n这是自动导入的内置库。 \n\n[使用手册相关文档](doc://library-guide/builtin/raw/api.md) string = 字符串函数库\n这是自动导入的内置库,\n[使用手册相关文档](doc://library-guide/builtin/string/matching.md) sys = 系统相关 thread = 线程函数库,\n这是自动导入的内置库 util = 语言扩展 web = 网页编程,\n声明了常用WINAPI函数,\n[使用手册相关文档](doc://library-guide/std/web/form/webform.html) win = 窗口操作,\n声明了常用WINAPI函数,\n[使用手册相关文档](doc://library-guide/std/win/_.html) winex = 外部窗口控制,\n[使用手册相关文档](doc://library-guide/std/winex/winex.html) wsock = 套接字 zeromq = 消息通讯 zlib = 压缩解压