# raw 库模块帮助文档

## raw 成员列表 <a id="raw" href="#raw">&#x23;</a>

原生接口编程与原生类型操作支持库。  
这是自动导入的内置库。   

[使用手册相关文档](https://www.aardio.com/zh-cn/docs/library-guide/builtin/raw/api.html)

### raw._release(内核对象) <a id="raw._release" href="#raw._release">&#x23;</a>
释放cdata类型内核对象,慎用.  
此函数保证不会重复释放已释放的内核对象,所以参数可以是已释放的内核对象,  
如果参数是cdata类型内核对象，或者参数的_topointer元方法中返回类型内核对象,则调用内核对象的_gc析构函数  
传入null会忽略不执行任何操作  

可用于释放cdata类型内核对象、com对象、IUnknown指针、com.interface创建的对象  
不能用于释放table.gc或gcdata创建的cdata对象

### raw.append <a id="raw.append" href="#raw.append">&#x23;</a>
此函数主要用于向缓冲区（ buffer ）或动态指针指向的内存追加数据。  
动态指针指一是使用 raw.realloc 函数分配的内存指针。  

要注意此函数与 string.concat 有较大的区别，string.concat 是拼接旧字符串返回新字符串。  
而 raw.append 是原地修改第一个参数指定的内存对象（ buffer 或动态指针 ）。  

使用此函数应当非常谨慎。  
- 写入动态指针时应当总是废弃传入的指针地址并自返回值接收新的指针地址。  
动态指针会自动分配足够的内存，但每次调用都可能更新指针地址。  
- 写入 buffer 前必须预先分配好足够的内存，buffer 是定长的无法改变大小。  

改用更强大的 string.builder 对象可以更安全更方便地向动态指针中追加数据。  
改用 raw.join 可以拼接 buffer 数组并返回新的 buffer 而不必受限于单个 buffer 的长度。

### raw.append(buffer,writeData,currentSize,writeSize) <a id="raw.append" href="#raw.append">&#x23;</a>
以二进制模式追加字符串到参数 @buffer 指定的缓冲区内。  
文本模式拼接请使用 string.concat 函数。  
- 参数 @buffer 必须是缓冲区（ buffer ）对象。  
- 参数 @writeData 可指定字符串、缓冲区（ buffer ）对象或者内存指针。  
- 参数 @currentSize 指定需要保留的前置数据长度，将在指定长度之后写入数据。  
- 参数 @writeSize 指定写入长度，  
如果 @writeData 是字符串或缓冲区则可省略 @writeSize（默认取 @writeData 的长度）  
此函数会检查 buffer 的总长度并自动调整 writeSize 到安全的范围并避免溢出。  

返回值为 currentSize + 实际写入的数值 ,返回长度不会超过 buffer 大小

### raw.append(dynPointer,writeData,writeSize) <a id="raw.append" href="#raw.append">&#x23;</a>
追加数据到动态指针分配的内存。  
- 参数 @dynPointer 必须是 raw.realloc 函数返回的`动态指针`  
如果内存长度不够时,此函数会自动调用 raw.realloc 调整内存大小。  
调用者必须弃用传入的 @dynPointer，并从返回值接收新的动态指针地址。  
- 参数 @writeData 可指定字符串、buffer、动态指针、普通指针、结构体  
如果指定字符串或 buffer 将在尾部添加`\u0000`（不计长度）  
- 可选用参数 @writeSize 指定要写入的数据长度。  
如果 @writeData 为指针、或动态指针则必须明确指定追加长度。  
- 可选用参数 @4 指定每次预分配内存的最小长度（ 默认为 1024 ）。

### raw.array <a id="raw.array" href="#raw.array">&#x23;</a>
此函数可在运行时创建一个结构体以表示确定长度的原生类型数组。  
例如 `raw.array(10,"int","items")` 会返回结构体 `{int items[10]=[]}`。  
也可以直接定义不指定长度的原生数组，并在运行时使用`纯数组`的 `length` 属性改变长度。  
示例：`{ int items[] = [ length: 10 ] }` 。

### raw.array() <a id="raw.array" href="#raw.array">&#x23;</a>
[返回对象:rawToArrayResultObject](#rawToArrayResultObject)

### raw.array(arrrayOrLength,typeName,fieldName) <a id="raw.array" href="#raw.array">&#x23;</a>
创建一个包含指定长度原生类型数组的结构体。  
- 参数 @arrrayOrLength 指定数组长度值，  
也可以指定用于初始化原生数组的 aardio 数组。  
- 参数 @typeName 指定数组元素类型,例如 "struct"。  
- 参数 @fieldName 指定数组字段名字，例如"items"。  
所有参数不可省略。  

raw.convertArray 可将指针直接转换为 aardio 普通数组，等价于:  
`raw.convert(pointer,raw.array(length,typeName,"items")).items`

### raw.buffer <a id="raw.buffer" href="#raw.buffer">&#x23;</a>
创建可读写、固定长度的内存块，用于读写二进制字节串，数据类型为 `buffer`。  
可用下标操作符 `[]` 读写 8 位无符号字节数值，可用 `#` 操作符取数组长度。  
不支持连接操作符 `++`，支持 raw.append,string.concat,string.join 等拼接函数。  

在几乎所有字符串函数中都可以作为字符串使用。  
在结构体中也可作为指针、 `BYTE[]` 数组的值。  
在原生 API 参数中可作为内存指针、字符串、输出字符串使用。  
在 COM 函数中可作为安全数组使用。

### raw.buffer(initialContent) <a id="raw.buffer" href="#raw.buffer">&#x23;</a>
创建可读写、固定长度的内存块，用于读写二进制字节串，数据类型为 `buffer`。  
参数可以是一个结构体、字符串、或 buffer,传入空表 `{}` 返回 null,  
分配新的内存并复制初始值指定的数据,返回 buffer 对象,  
buffer 在多数字符串函数中都可以作为字符串使用  
在 API 中可以作为字符串、指针、字节串使用。  
在 COM 函数中可作为安全数组使用  

buffer 在 JSON 中会转换为 `{type="Buffer";data=[] }` 格式的表对象,  
这种表对象可作为 raw.buffer 的唯一参数还原为 buffer 对象。

### raw.buffer(size,initialContent) <a id="raw.buffer" href="#raw.buffer">&#x23;</a>
创建可读写、固定长度的内存块，用于读写二进制字节串，数据类型为 `buffer`。  
参数 @size 指定需要分配的内存大小,  
参数 @initialContent 可以使用结构体、指针、buffer、或字符串指定初始填充的数据,  
也可用一个数值指定所有字节的初始字节码,不指定默认初始化所有字节码为 0,  

如果初始值指定为字符串或 buffer 类型，  
填充初始数据以后剩余的字节会清零。  

buffer 存储的是二进制字节串,可使用下标操作符读写字节码。  
buffer 在多数字符串函数中都可以作为字符串使用。  
在原生 API 中可以作为字符串、指针、字节数组使用。

### raw.byte() <a id="raw.byte" href="#raw.byte">&#x23;</a>
转换参数@1指定的数值为 byte 类型数值（8位整数）包装对象,  
返回对象支持 tonumber tostring 等类型转换函数。  

用于调用非声明式原生 API 函数的参数,  
默认传值,参数@2为 true 则用于传址参数（传数值的指针）。  

用于 COM 函数参数则总是传值, COM 函数也可使用 com.byte 函数

[返回对象:rawNumberObject](#rawNumberObject)

### raw.closehandle() <a id="raw.closehandle" href="#raw.closehandle">&#x23;</a>
关闭句柄资源

### raw.convert <a id="raw.convert" href="#raw.convert">&#x23;</a>
转换并返回结构体

### raw.convert(源指针,目标结构体,字节单位偏移,结构体单位偏移) <a id="raw.convert" href="#raw.convert">&#x23;</a>
读取内存数据到目标结构体，返回目标结构体,  
参数@1可以是指针、buffer、字符串,  
可选用参数@3指定在源指针上按字节单位计数的偏移位置,不指定默认为0,  
如果在参数@4指定了按结构体为单位大小的偏移位置,则忽略参数@3

### raw.convert(源结构体,目标指针,字节单位偏移,结构体单位偏移) <a id="raw.convert" href="#raw.convert">&#x23;</a>
把结构体写入内存，返回内存指针,  
参数@2可以是指针、buffer,  
可选用参数@3指定在目标指针上按字节单位计数的偏移位置,不指定默认为0,  
如果在参数@4指定了按结构体为单位大小的偏移位置,则忽略参数@3

### raw.convert(源结构体,目标结构体) <a id="raw.convert" href="#raw.convert">&#x23;</a>
转换结构体，返回目标结构体

### raw.convertArray(源内存指针,源数组长度,"数据类型",偏移量) <a id="raw.convertArray" href="#raw.convertArray">&#x23;</a>
将指针指向的内存转换为普通数组，传入空指针返回 null 。  
参数 @3 （数据类型）可省略，默认为"pointer"  
参数 @3 也可以直接传入一个结构体（类或实例）以指定数据类型。  
参数 @4 可选指定偏移量（以字节为单位），默认为 0  

此函数不会检测内存溢出错误,调用代码必须保证参数是正确的值

### raw.copy <a id="raw.copy" href="#raw.copy">&#x23;</a>
复制内存数据

### raw.copy(destPinterOrBuffer,srcData,size) <a id="raw.copy" href="#raw.copy">&#x23;</a>
复制内存数据。  
- 参数 @destPinterOrBuffer 指定复制目标（ 指针或 buffer 类型参数 ）。  
- 参数 @srcData 允许使用指针,buffer,字符串,或结构体参数。  
此函数不允许其他可自动转换为指针的非指针类型参数。  
- 参数 @size 指定要复制的字节长度。  

  如果复制源或目标是 buffer，字符串,或结构体等可获取内存长度的类型，可以省略参数 @size 。  
  如果 aardio 能获取复制源或复制目标的内存长度则复制长度不会超过可用长度。  
  但如果参数是指针将无法检测内存长度，请自行计算好参数避免溢出。  

  如果未显式指定复制长度，并且 @srcData 是 buffer，或字符串时，  
  将复制全部数据与尾部隐藏的`\u0000`到目标内存，如果复制目标是指针，  
  那么要保证复制源加上这 2 个字节也不会超过目标内存长度。  

raw.copy2 函数支持相同功能，但可以指定更多参数（可指定源内存与目标内存偏移量）

### raw.copy2 <a id="raw.copy2" href="#raw.copy2">&#x23;</a>
复制内存。  
此函数内部调用 raw.copy ，但 raw.copy2 可指定更多参数。

### raw.copy2(destPinterOrBuffer,dstOffset,srcData,srcOffset,copySize) <a id="raw.copy2" href="#raw.copy2">&#x23;</a>
- 参数 @destPinterOrBuffer 可指定 buffer 或内存指针。  
- 参数 @dstOffset 指定目标内存偏移量，虽然数组索引自 1 开始，但内存偏移量自 0 开始。  
指定非 0 偏移量则将 @destPinterOrBuffer 转为指针传给 raw.copy 函数。  
- 参数 @srcData 可指定字符串、buffer、结构体、指针  
如果 @srcData 为结构体则不应指定 @srcOffse 与 @copySize 参数。  
- 参数 @srcOffset 指定复制源内存（指 @srcData ）的偏移量，省略则为 0。  
指定非 0 偏移量则将 @srcData 转为指针传给 raw.copy 函数。  
- 参数 @copySize 指定复制长度（字节数）   
如果参数 @srcData 是 buffer,字符串、结构体等可确定长度的对象，  
且未指定 @srcOffset 参数时可以省略 @copySize 参数。

### raw.double() <a id="raw.double" href="#raw.double">&#x23;</a>
转换参数@1指定的数值为 double 类型数值（64位浮点数）包装对象,  
返回对象支持 tonumber tostring 等类型转换函数。  

用于调用非声明式原生 API 函数的参数,  
默认传值,参数@2为 true 则用于传址参数（传数值的指针）。  

用于 COM 函数参数则总是传值, COM 函数也可使用 com.double 函数

[返回对象:rawNumberObject](#rawNumberObject)

### raw.dup(源句柄,源进程,目标进程,允许子进程继承) <a id="raw.dup" href="#raw.dup">&#x23;</a>
返回复制的系统句柄  
除参数1之外,其他参数可选  
默认仅在当前进程中复制句柄  
复制的句柄应使用 raw.closeHandle 释放

### raw.equal <a id="raw.equal" href="#raw.equal">&#x23;</a>
比较内存存储的数据是否相同。  

注意 buffer 直接用 `==` 操作符只能比较地址不能比较内容，  
但 aardio 中相同内容的字符串总是指向同一地址，因此字符串可以直接用 `==` 比较。  

相关函数: string.cmp

### raw.equal(data1,data2,size) <a id="raw.equal" href="#raw.equal">&#x23;</a>
二进制比较 @data1,@data2 存储的数据是否相同。  

- 参数 @data1,@data2 可指定字符串,buffer,结构体,null，指针以及可转为指针的对象。  
调用者必须确认指针参数所指向的内存不小于待比较的长度。  
对于字符串,buffer,结构体,null 等参数，长度小于待比较长度时返回 false 。  
注意 null 与 "" 不相等。  

- 可选用参数 @size 自定义比较长度。  
如果 @data1 或 @data2 可以确定长度则 @size 可以省略。  
省略 @size 参数并且 @data1,@data2 可以确定长度不相等时直接返回 false 。  

如果仅执行文本（不包含空字符 `\0`）比较应改用更合适的 string.cmp 函数。

### raw.execute <a id="raw.execute" href="#raw.execute">&#x23;</a>
运行外部程序，成功返回 true。  
 process.execute 函数提供类似的功能，区别可参考函数源码

### raw.execute(file,param,operation,showCmd,workDir,hwnd) <a id="raw.execute" href="#raw.execute">&#x23;</a>
运行外部程序，成功返回 true。  
@file 指定要运行的程序路径，其他所有参数可省略，  
@param 字符串参数，可选指定启动参数。  
@operation 可选用一个字符串指定执行动词，省略则使用默认动词或 "open"。  
@showCmd 可选用 _SW_ 前缀常量指定显示选项，默认为 _SW_SHOW。  
@workDir 参数可选指定工作目录。  
@hwnd 可选指定所有窗口句柄，默认取当前线程活动窗口

### raw.explore(path,args,...) <a id="raw.explore" href="#raw.explore">&#x23;</a>
使用资源管理器（Explorer.exe）打开文件或目录。  
第一个参数 @path 指定文件路径，可为空值（ null ）。  
注意 Explorer.exe 不解析标准的命令行参数转义符，这一点与其他程序不同。  
如参数 @path 尾部有双反斜杠`\\`则为无效路径并打开默认目录（打开我的文档，XP系统报错）。  
如参数 @path 指定为 ","或"file:" 则打开“此电脑（This PC）”。  
如参数 @path 使用`shell:::`前缀则可以指定特殊路径的 CLSID。  

可用第二个参数 @args 或更多参数指定 Explorer.exe 命令行选项，  
例如指定  "/select" 在资源管理器选择指定路径。  
注意 "/n" 等选项在新系统中是无意义的，Explorer 将总是打开新窗口。

### raw.find <a id="raw.find" href="#raw.find">&#x23;</a>
用法与string.find相同  
区别是参数@1允许使用内存指针  
并必须使用参数@2指定查找数据的内存长度  
指定错误的指针或长度会导致内存错误，请谨慎使用此函数

### raw.find(指针,内存长度,"查找模式",开始位置) <a id="raw.find" href="#raw.find">&#x23;</a>
使用模式串在字符串中查找子串的位置，  
参数 @1 可以使用指针、字符串、或 buffer  
无论指定任何类型,内存长度都不可省略,aardio不会检测指定的内存长度是否错误  

- 开始位置为可选参数，默认为1（起始位置），必须以字节计数，可用负数表示尾部倒计数。  
转换后的开始位置如果仍然小于 1 则设为 1，大于总长度则直接返回 null。  

匹配失败返回 null，成功则返回匹配结果的起始,结束位置，以及所有捕获分组。  
如果有多个捕获分组,将附加为多个返回值

### raw.float() <a id="raw.float" href="#raw.float">&#x23;</a>
转换参数@1指定的数值为 float 类型数值（32位浮点数）包装对象,  
返回对象支持 tonumber tostring 等类型转换函数。  

用于调用非声明式原生 API 函数的参数,  
默认传值,参数@2为 true 则用于传址参数（传数值的指针）。  

用于 COM 函数参数则总是传值, COM 函数也可使用 com.float 函数

[返回对象:rawNumberObject](#rawNumberObject)

### raw.indexOf <a id="raw.indexOf" href="#raw.indexOf">&#x23;</a>
与 string.indexOf 类似，  
主要的区别是 raw.indexOf 的参数 @1 允许使用内存指针，  
但必须使用参数 @2 指定指针指向的内存长度。  
指定错误的指针或长度会导致内存错误，请谨慎使用此函数。

### raw.indexOf(指针,查找内存长度,查找字符串,起始索引) <a id="raw.indexOf" href="#raw.indexOf">&#x23;</a>
使用模式串在字符串中查找子串的位置。  
- 参数 @1 可以使用指针、字符串、或 buffer 。  
参数 @1 如果是指针则内存长度都不可省略（aardio 不会检测指定的内存长度是否错误）。  
如果参数 @1 是 string/buffer 则可以自动获取最大长度（参数必须保留占位：留空/null）。  
- 开始位置为可选参数，默认为1（起始位置），必须以字节计数，可用负数表示尾部倒计数。  
转换后的开始位置如果仍然小于 1 则设为 1，大于总长度则直接返回 null。  

函数返回匹配结果的起始位置

### raw.int() <a id="raw.int" href="#raw.int">&#x23;</a>
转换参数@1指定的数值为 int 类型数值（32位整数）包装对象,  
返回对象支持 tonumber tostring 等类型转换函数。  

用于调用非声明式原生 API 函数的参数,  
默认传值,参数@2为 true 则用于传址参数（传数值的指针）。  

用于 COM 函数参数则总是传值, COM 函数也可使用 com.int 函数

[返回对象:rawNumberObject](#rawNumberObject)

### raw.join(字节串数组,分隔字符串,起始索引,结束索引) <a id="raw.join" href="#raw.join">&#x23;</a>
拼接参数 @1 指定的字符串或 buffer 数组，返回 buffer 对象。  
- 参数 @1不可包含除字符串, buffer, null 之外其他类型的值，忽略 null 值元素。  
包含 buffer 的数组只能用 raw.join 拼接，不可使用 string.join 拼接。  
- 参数 @2 可选指定一个分隔字符串。  
- 起始索引与结束索引为可选参数，可传入负数表示自数组尾部倒计数  

如果拼接后字节长度为 0，此函数返回 null。  
起始索引与结束索引可用负数表示倒计数，索引溢出则自动设为最接近的有效索引。  
如果转换后的起始索引大于结束索引此函数返回 null。

### raw.len(buffer、字符串或结构体) <a id="raw.len" href="#raw.len">&#x23;</a>
返回参数 @1 指定的字符串、buffer 或结构体的字节长度。  
传入其他类型参数返回 null 值。  

相关函数： raw.sizeof

### raw.loadDll <a id="raw.loadDll" href="#raw.loadDll">&#x23;</a>
加载 DLL  
DLL变量名如果为全局变量,首字母必须大写且必须按如下格式赋值  
::User32 := raw.loadDll("User32.dll")  

如果DLL厂商仅提供一个版本的DLL，一般是32位的DLL，在aardio可以直接加载，  
如果DLL厂商提供了64位、32位两个版本的DLL，这时候你需要选择32位版本的DLL才能加载，  
aardio程序也是32位的，主要是因为64位程序只能运行在64位平台，而32位程序兼容所有平台。  

32位的进程的内存限制仅仅是限制单个进程的内存，  
实际上一般的桌面软件基本都不可能用到好几个GB的内存  
目前aardio提供process.command可以很方便的使用使用多进程交互  
如果软件使用外部数据库、或者其他服务端口，因为跨进程都不会受单进程的内存限制。  
编写网站的FastCGI同样是多进程模式。

### raw.loadDll("DLL路径","共享名字","调用约定") <a id="raw.loadDll" href="#raw.loadDll">&#x23;</a>
第一个参数可以是 DLL 路径或 DLL 内存数据。  
载入内存 DLL 数据时,可使用参数 @2 指定共享模块名称以启用共享模式。  
如果 DLL 本身是库文件,则共享名称建议使用库命名空间路径。  
参数 @3 可选指定调用约定,默认为`stdcall,microsoft`  
指定为 `cdecl`使用 C语言调用约定，其他调用约定请查看文（其他值较罕见）。  

路径首字符可用斜杠表示应用程序根目录，路径开始用`~`加斜杠表示 EXE 根目录  
如果`~\`或`~/`开头的 EXE 根目录路径不存在，自动转换为应用程序根目录下的路径重试。  
在文件路径前加 `$` 操符符表示将文件编译为内存字符串并加载内存 DLL。  

如果 DLL 文件依赖同目录下的其他 DLL 文件，而这些 DLL 不在默认搜索目录顺序内时，  
aardio 将会自动调用 `::Kernel32.SetDllDirectory` 修正问题，  
并在操作完成后自动恢复默认设置。

### raw.loadDll() <a id="raw.loadDll" href="#raw.loadDll">&#x23;</a>
[返回对象:dllModuleObject](https://www.aardio.com/zh-cn/docs/library-reference/raw/_.html#dllModuleObject)

### raw.long() <a id="raw.long" href="#raw.long">&#x23;</a>
转换参数@1指定的数值为 long 类型数值（64位整数）包装对象,  
返回对象支持 tonumber tostring 等类型转换函数。  

用于调用非声明式原生 API 函数的参数,  
默认传值,参数@2为 true 则用于传址参数（传数值的指针）。  

用于 COM 函数参数则总是传值, COM 函数也可使用 com.long 函数

[返回对象:rawNumberObject](#rawNumberObject)

### raw.main <a id="raw.main" href="#raw.main">&#x23;</a>
进程主模块,默认调用约定为stdcall  
与raw.module("stdcall")返回的值相同,  
可用于将当前进程中的函数指针转换为aardio函数  

[返回对象:dllModuleObject](https://www.aardio.com/zh-cn/docs/library-reference/raw/_.html#dllModuleObject)

### raw.match <a id="raw.match" href="#raw.match">&#x23;</a>
用法与string.match相同  
区别是参数 @1 允许使用内存指针  
并必须使用参数 @2 指定查找数据的内存长度  
指定错误的指针或长度会导致内存错误，请谨慎使用此函数

### raw.match(指针,内存长度,"模式串",开始位置) <a id="raw.match" href="#raw.match">&#x23;</a>
使用模式串在字符串中查找子串，  
参数@1可以使用指针、字符串、或 buffer,  
无论指定任何类型,内存长度都不可省略,aardio不会检测指定的内存长度是否错误  
参数@3指定查找模式串。  
- 开始位置为可选参数，默认为1（起始位置），必须以字节计数，可用负数表示尾部倒计数。  
转换后的开始位置如果仍然小于 1 则设为 1，大于总长度则直接返回 null。  

返回匹配字符串,如果使用了捕获组则返回多个对应的匹配串,  
返回值的顺序对应模式串中左圆括号的开始顺序

### raw.mixin(指针,结构体对象,任意个混入表...) <a id="raw.mixin" href="#raw.mixin">&#x23;</a>
如果未指定参数 @3 此函数将参数 @2 指定的结构体复制到参数 @1 指定的内存，  
然后返回结构体。  

否则将参数 @1 指定的内存数据先复制到参数 @2 指定的结构体。  
然后将后续的所有表参数（仅包含需要修改的字段）调用  table.assign 函数混入到结构体中。  
然后再将被填充的结构体复制到参数 @1 指定的内存。  

例如代码 `raw.minxin(ptr,{int x;int y},{y=123})` 只会修改内存中的 y 字段。  
而 `raw.minxin(ptr,{int x;int y})` 则会将 x,y 字段都清零。

### raw.module("调用约定") <a id="raw.module" href="#raw.module">&#x23;</a>
指定约定并返回进程主模块,   
省略参数时调用约定默认为stdcall,  
可用于将当前进程中的函数指针转换为aardio函数,

### raw.module() <a id="raw.module" href="#raw.module">&#x23;</a>
[返回对象:dllModuleObject](https://www.aardio.com/zh-cn/docs/library-reference/raw/_.html#dllModuleObject)

### raw.realloc <a id="raw.realloc" href="#raw.realloc">&#x23;</a>
快速分配内存并返回动态指针  
aardio会在"动态指针"头部倒退8个字节记录内存以及存储内容长度,  
动态指针的头部结构体如下：  

```aardio  
{  
    INT capacity;//记录预分配的内存容量  
    INT size;//记录存储的数据长度  
}  
```  

动态指针指向的内存尾部隐藏2个字节并放置``'\u0000'``(不计入内存长度)  
"动态指针"可作为普通指针使用,并可用于 raw.append 函数快速拼接数据  
使用此函数将"动态指针"的长度设为0时可释放内存  
"动态指针"不会被自动回收,必须手动释放

### raw.realloc(0,动态指针) <a id="raw.realloc" href="#raw.realloc">&#x23;</a>
长度指定为0则释放"动态指针",指针参数为null时忽略不报错  
建议使用传入"动态指针"的变量接收空的返回值,以避免误用失效的指针变量

### raw.realloc(内存长度) <a id="raw.realloc" href="#raw.realloc">&#x23;</a>
快速分配内存并返回指针,  
可选用参数3指定分配内存中所有字节的初始值  
初始值可指定所有字节的字节码,也可指定字符串、结构体  
返回分配的指针,该指针可作为普通指针使用  
指针不会被自动回收,必须手动释放

### raw.realloc(内存长度,动态指针,初始值) <a id="raw.realloc" href="#raw.realloc">&#x23;</a>
调整内存大小,可能返回新指针  
传入指针必须弃用,返回值是新的指针必须手动释放,  
可选用参数3指定分配内存中所有字节的初始值,  
初始值可指定所有字节的字节码,也可指定字符串、结构体  
指定初始值会重置指针记录的数据长度  

如果指定的初始值为字符串或 buffer，  
并且其长度超过了动态指定已分配的内存长度，  
则aardio会自动截断放不下去的尾部数据。

### raw.remoteApi <a id="raw.remoteApi" href="#raw.remoteApi">&#x23;</a>
在外部进程内创建远程调用函数

### raw.remoteApi(目标进程,"void()","dll名","函数名") <a id="raw.remoteApi(目标进程,"void" href="#raw.remoteApi(目标进程,"void">&#x23;</a>
参数(进程ID或句柄,函数原型,加载DLL模块名,函数名,调用约定)   
不指定调用约定时默认使用stdcall调用约定  
不会在API函数名字后面自动添加或移除"A","W"编码声明后缀,  
并且要注意搜索DLL时默认搜索路径包含目标EXE所在目录,而非当前EXE目录

### raw.remoteApi(目标进程,"void()","dll名","函数名","cdecl") <a id="raw.remoteApi(目标进程,"void" href="#raw.remoteApi(目标进程,"void">&#x23;</a>
参数(进程ID或句柄,函数原型,加载DLL模块名,函数名,调用约定)   
不会在API函数名字后面自动添加或移除"A","W"编码声明后缀,  
并且要注意搜索DLL时默认搜索路径包含目标EXE所在目录,而非当前EXE目录

### raw.remoteApi(目标进程,"void()",CALL地址,调用约定) <a id="raw.remoteApi(目标进程,"void" href="#raw.remoteApi(目标进程,"void">&#x23;</a>
参数(进程ID或句柄,函数原型,CALL地址,调用约定)   
参数@1可以是进程ID，也可以是进程句柄(此函数不负责关闭该句柄)  
注意参数@1不能指定当前进程ID或句柄,  
不指定调用约定在数时默认使用stdcall调用约定

### raw.remoteApi(目标进程,"void(INT thisAddr)","dll名","函数名","thiscall") <a id="raw.remoteApi(目标进程,"void" href="#raw.remoteApi(目标进程,"void">&#x23;</a>
参数(进程ID或句柄,函数原型,加载DLL模块名,函数名,调用约定)  
thiscall使用第一个参数指定this指针地址  
不会在API函数名字后面自动添加或移除"A","W"编码声明后缀,  
并且要注意搜索DLL时默认搜索路径包含目标EXE所在目录,而非当前EXE目录

### raw.serializeDupHandle("类名",句柄) <a id="raw.serializeDupHandle" href="#raw.serializeDupHandle">&#x23;</a>
复制进程内有效句柄并序列化对象  
只能用于_serialize元方法，且必须kernelCall参数为真  
序列化类构造函数必须支持指针参数1为指针类型句柄,参数2为true的参数  
并负责在析构函数中调用 raw.closeHandle 释放该句柄

### raw.sizeof <a id="raw.sizeof" href="#raw.sizeof">&#x23;</a>
计算原生类型大小。  

相关函数： raw.len

### raw.sizeof( ) <a id="raw.sizeof" href="#raw.sizeof">&#x23;</a>
返回结构体、原生类型、动态指针内存长度。  
参数 @1 可指定结构体、或包含原生类型名称的字符串。  
- 参数 @1 如果是指针，则必须是通过 raw.realloc 函数创建的动态指针,  
传入动态指针，返回 2 个值，分别为存储数据长度、分配内存总长度。  
传入其他来源指针，因缺少动态指针头信息会导致崩溃。  
- 参数 @1 传入 null 值返回 0。  
- 无参数时会报错抛出异常。

### raw.slice <a id="raw.slice" href="#raw.slice">&#x23;</a>
截取字节串并返回新的 buffer 对象。

### raw.slice(buffferOrPtr,startIndex,endIndex,size) <a id="raw.slice" href="#raw.slice">&#x23;</a>
- 参数 @buffferOrPtr 可指定 buffer,字符串或指针。  
- 参数 @startIndex 指定截取开始位置，参数 @endIndex 指定最后一个截取字节的位置。  
省略 @startIndex 则默认为 1,省略 @endIndex 则默认为 @size  
如果 @startIndex,endIndex 为负数则表示自尾部倒计数，-1 表示最后一个字节。  
如果转换后 @startIndex 小于 1 则设为 1，@endIndex 大于 size 则设为 size。  
如果 @startIndex 大于 1，@endIndex 则返回 null 值。  
- 参数 @size 指定字节串长度，如果参数 @1 指定字符串或 buffer 则可省略 size 参数。

### raw.str <a id="raw.str" href="#raw.str">&#x23;</a>
转换为纯文本字符串(去掉尾部多余终结符)  
参数为空返回null  

如果输入参数是字符串，应当改用 string.str 函数

### raw.str(指针,是否unicode,偏移) <a id="raw.str" href="#raw.str">&#x23;</a>
转换为纯文本字符串(去掉尾部多余终结符)  
参数一可以是指针或buffer,其余参数可省略,偏移默认为0  
参数@2为true反回字符串标记会设置UTF-16标记,否则设为UTF-8标记,  
注意此函数并不会转换编码,不可指定错误的编码参数  
参数为空返回null

### raw.str(结构体,是否unicode) <a id="raw.str" href="#raw.str">&#x23;</a>
结构体内存数据转换为文本字符串  
参数@2为 true 返回字符串标记会设置 UTF-16 标记,否则设为 UTF-8 标记  
注意此函数并不会转换编码,不可指定错误的编码参数

### raw.swap(数值,"INT"); <a id="raw.swap" href="#raw.swap">&#x23;</a>
反向转换整数的大小端字节序。  
参数 @2 指定原生数据类型，可指定为：  
"INT","int","WORD","word","LONG","long",大写表示无符号数。  
省略则默认为"INT"。  
如果参数 @1 指定  math.size64 对象，则参数 @2 必须为 `LONG`。  
指定 math.size64 对象时转换并返回对象自身而非新值。  
直接调用 math.size64 对象的 swap 方法则会返回新值（不改变自身）。  
类型为 "long" 则有效转换的上下限为为正负 `2**52`，  
超出范围的值仅具存储作用（可用 string.format 的 `%d` 格式码转为字符串）。

### raw.toPointer <a id="raw.toPointer" href="#raw.toPointer">&#x23;</a>
获取对象的临时指针。  
获取的指针在源对象失效时也会失效，并且无法阻止源对象被回收。  
此函数获取的指针只能临时使用，不应当长久保存，并应当尽快弃用。  
此函数能不用就尽量不要用。

### raw.toPointer(anyPointerConvertible,offset) <a id="raw.toPointer" href="#raw.toPointer">&#x23;</a>
获取参数 @anyPointerConvertible 的临时指针,可选用参 数@offset 指定偏移值。  
所有可用于 API 函数 pointer 类型的对象都可以用此函数提取指针。  
例如指针、字符串、buffer、所有定义了 _topointer 元方法的对象。  
普通结构体必须转为 buffer 才能提取指针。  
参数 @anyPointerConvertible 不能是数值,数值转指针请改用 topointer 函数。  

滥用此函数提取对象的原始指针在很多时候是不必要且不安全的，  
如果在原对象被回收以后，仍然在错误的使用获得的指针，会让程序变得不稳定。  
除非你知道自己在做什么否则请不要使用此函数。  
实际上 buffer, 结构体等对象在很多函数里都可以直接作为指针使用，  
这样更安全、更稳定、代码更简洁，也避免了不必要的函数调用。

### raw.tocdecl <a id="raw.tocdecl" href="#raw.tocdecl">&#x23;</a>
创建cdecl调用约定的原生回调函数,  

应保持原生回调函数在有效作用域内,否则会自动释放,  
函数返回值应当先赋值到变量而不是直接写到调用参数里,  
这会导致函数未返回但原生回调函数可能已释放。  

如果原生回调函数被指定为某对象的成员,在函数内部又循环引用了该对象,  
这会导致无法释放资源。使用参数@3将该对象指定为owner可避免该问题

### raw.tocdecl(函数,"int()",owner) <a id="raw.tocdecl(函数,"int" href="#raw.tocdecl(函数,"int">&#x23;</a>
参数@2与API声明语法相同,可使用&表示输出参数,  
例如C中的int *指针在aardio回调中声明为int &  
有几个输出参数,就可增加相应个数的返回值用于更新输出参数值,  
未返回的输出结构体参数忽略不更新传入的结构体。  

回调参数声明可直接指定结构体,传入实参必须是结构体指针,  
结构体声明不能再嵌套结构体,不能包含变量,  
示例：`raw.tocdecl(func,"int({int x;int y} &pt)")`  

返回值类型检测比输出参数宽松,数值,布尔值、null值可按C规则兼容转换,  
返回值传结构体时必须返回不大于64位的结构体,且传值而非传址

### raw.tofastcall <a id="raw.tofastcall" href="#raw.tofastcall">&#x23;</a>
创建 ms-fastcall 调用约定的原生回调函数  
注意前两个参数不能大于32位,  

应保持原生回调函数在有效作用域内,否则会自动释放,  
函数返回值应当先赋值到变量而不是直接写到调用参数里,  
这会导致函数未返回但原生回调函数可能已释放。  

如果原生回调函数被指定为某对象的成员,在函数内部又循环引用了该对象,  
这会导致无法释放资源。使用参数@3将该对象指定为owner可避免该问题

### raw.tofastcall(函数,"int()",owner) <a id="raw.tofastcall(函数,"int" href="#raw.tofastcall(函数,"int">&#x23;</a>
参数@2与API声明语法相同,可使用&表示输出参数,  
例如C中的int *指针在aardio回调中声明为int &  
有几个输出参数,就可增加相应个数的返回值用于更新输出参数值,  
未返回的输出结构体参数忽略不更新传入的结构体。  

回调参数声明可直接指定结构体,传入实参必须是结构体指针,  
结构体声明不能再嵌套结构体,不能包含变量,  
示例：`raw.tocdecl(func,"int({int x;int y} &pt)")`  

返回值类型检测比输出参数宽松,数值,布尔值、null值可按C规则兼容转换,  
返回值传结构体时必须返回不大于64位的结构体,且传值而非传址

### raw.tostdcall <a id="raw.tostdcall" href="#raw.tostdcall">&#x23;</a>
创建stdcall调用约定的原生回调函数,  

应保持原生回调函数在有效作用域内,否则会自动释放,  
函数返回值应当先赋值到变量而不是直接写到调用参数里,  
这会导致函数未返回但原生回调函数可能已释放。  

如果原生回调函数被指定为某对象的成员,在函数内部又循环引用了该对象,  
这会导致无法释放资源。使用参数@3将该对象指定为owner可避免该问题

### raw.tostdcall(函数,"int()",owner) <a id="raw.tostdcall(函数,"int" href="#raw.tostdcall(函数,"int">&#x23;</a>
参数@2与API声明语法相同,可使用&表示输出参数,  
例如C中的int *指针在aardio回调中声明为int &  
有几个输出参数,就可增加相应个数的返回值用于更新输出参数值,  
未返回的输出结构体参数忽略不更新传入的结构体。  

回调参数声明可直接指定结构体,传入实参必须是结构体指针,  
结构体声明不能再嵌套结构体,不能包含变量,  
示例：`raw.tocdecl(func,"int({int x;int y} &pt)")`  

返回值类型检测比输出参数宽松,数值,布尔值、null值可按C规则兼容转换,  
返回值传结构体时必须返回不大于64位的结构体,且传值而非传址

### raw.tostring( ) <a id="raw.tostring" href="#raw.tostring">&#x23;</a>
将结构体、指针、或 buffer 对象转换为普通字符串  
参数如果是结构体不需要指定截取位置  
参数如果是 buffer 类型，自动获取 buffer 长度并设为截取长度  
参数如果是指针且未指定长度时，以`'\0'`为终止符并设为截取长度，  
转换为不包含`'\0'`的文本字符串,建议改用 raw.str 函数

### raw.tostring( , start,end) <a id="raw.tostring" href="#raw.tostring">&#x23;</a>
将指针、或 buffer 对象转换为普通字符串  
start指定开始位置(省略则默认设为1),end指定结束位置,  

如果未指定结束位置参数，  
参数如果是buffer类型，自动获取buffer长度并设为结束位置  
参数如果是指针，以`'\0'`为终止符并设为结束位置

### raw.typeOfArray() <a id="raw.typeOfArray" href="#raw.typeOfArray">&#x23;</a>
如果参数是一个包含原生数组的结构体，  
返回原生类型名，以及数组字段名字。  
如果是其他对象则返回 null 。

### raw.ubyte() <a id="raw.ubyte" href="#raw.ubyte">&#x23;</a>
转换参数@1指定的数值为 BYTE 类型数值（8位无符号整数）包装对象,  
返回对象支持 tonumber tostring 等类型转换函数。  

用于调用非声明式原生 API 函数的参数,  
默认传值,参数@2为 true 则用于传址参数（传数值的指针）。  

用于 COM 函数参数则总是传值, COM 函数也可使用 com.ubyte 函数,  
注意在原生类型中使用大写的 BYTE 类型表示8位无符号整数

[返回对象:rawNumberObject](#rawNumberObject)

### raw.uint() <a id="raw.uint" href="#raw.uint">&#x23;</a>
转换参数@1指定的数值为 INT 类型数值（32位无符号整数）包装对象,  
返回对象支持 tonumber tostring 等类型转换函数。  

用于调用非声明式原生 API 函数的参数,  
默认传值,参数@2为 true 则用于传址参数（传数值的指针）。  

用于 COM 函数参数则总是传值, COM 函数也可使用 com.uint 函数,  
注意在原生类型中使用大写的 INT 类型表示32位无符号整数

[返回对象:rawNumberObject](#rawNumberObject)

### raw.ulong() <a id="raw.ulong" href="#raw.ulong">&#x23;</a>
参数@1可传入数值或 math.size64 对象,  
返回适用于 LONG 类型数值（64位无符号整数）的包装对象,  
返回对象支持 tonumber tostring 等类型转换函数。  

用于调用非声明式原生 API 函数的参数,  
默认传值,参数@2为 true 则用于传址参数（传数值的指针）。  

用于 COM 函数参数则总是传值, COM 函数也可使用 com.ulong 函数,  
注意在原生类型中使用大写的 LONG 类型表示64位无符号整数

[返回对象:rawNumberObject](#rawNumberObject)

### raw.uword() <a id="raw.uword" href="#raw.uword">&#x23;</a>
转换参数@1指定的数值为 WORD 类型数值（16位无符号整数）包装对象,  
返回对象支持 tonumber tostring 等类型转换函数。  

用于调用非声明式原生 API 函数的参数,  
默认传值,参数@2为 true 则用于传址参数（传数值的指针）。  

用于 COM 函数参数则总是传值, COM 函数也可使用 com.uword 函数,  
注意在原生类型中使用大写的 WORD 类型表示16位无符号整数

[返回对象:rawNumberObject](#rawNumberObject)

### raw.word() <a id="raw.word" href="#raw.word">&#x23;</a>
转换参数@1指定的数值为 word 类型数值（16位整数）包装对象,  
返回对象支持 tonumber tostring 等类型转换函数。  

用于调用非声明式原生 API 函数的参数,  
默认传值,参数@2为 true 则用于传址参数（传数值的指针）。  

用于 COM 函数参数则总是传值, COM 函数也可使用 com.word 函数

[返回对象:rawNumberObject](#rawNumberObject)

## dllModuleObject 成员列表 <a id="dllModuleObject" href="#dllModuleObject">&#x23;</a>

### dllModuleObject.* <a id="dllModuleObject.any" href="#dllModuleObject.any">&#x23;</a>
可不用声明直接在此输入函数名并调用API函数  

一、传入参数规则：  
1、调用约定在加载DLL的参数中指定,支持cdecl不定个数参数  
2、null参数不可省略  
3、32位整数类型，小于32位的整数、以及枚举类型都可以直接在API参数中写数值。  
4、对于任何数值类型的指针（输出参数）一律使用结构体表示，例如double * v 表示为{ double v }  
5、数组使用结构体表示  
6、所有结构体传给API的都是指针地址，都是输出参数并增加返回值  

二、返回值规则：  
1、返回值默认为int类型,可用 >>> 0 强制转为无符号数,  
2、可以使用[API尾标]改变返回值为其他类型  

三、所有可用的【API尾标】:  
dll.ApiNameW() 切换到Unicode版本，字符串UTF8-UTF16双向转换  
dll.ApiNameA() 切换到ANSI版本,字符串不作任何转换  
dll.ApiNameL() 返回值为 math.size64 对象（64位无符号 LONG 类型）  
dll.ApiNameP() 返回值为指针类型  
dll.ApiNameD() 返回值为double浮点数  
dll.ApiNameF() 返回值为float浮点数  
dll.ApiNameB() 返回值为C++中的8位bool类型  
注意尾标必须大写且尾标前没有大写字符,  
API 已含W尾标时可省略，API以'_w'结尾也按 Unicode 版本处理。

### dllModuleObject.api("字符串参数","void()" ) <a id="dllModuleObject.api("字符串参数","void" href="#dllModuleObject.api("字符串参数","void">&#x23;</a>
声明API函数,参数(函数名,函数原型,调用约定="stdcall,microsoft")  
可选使用参数3指定调用约定,默认值为"stdcall,microsoft",  
返回值为原生函数对象（ cdata 类型 ）

### dllModuleObject.api("字符串参数","void()" ,"cdecl") <a id="dllModuleObject.api("字符串参数","void" href="#dllModuleObject.api("字符串参数","void">&#x23;</a>
声明API函数,参数(函数名,函数原型,调用约定)  
参数3使用一个字符串指定调用约定,逗号后面可选指定开发工具厂商,  
返回值为原生函数对象（ cdata 类型 ）

### dllModuleObject.api(函数名,函数原型,调用约定,this指针) <a id="dllModuleObject.api" href="#dllModuleObject.api">&#x23;</a>
声明API函数,  
返回值为原生函数对象（ cdata 类型 ）,  
参数@1也可以指定导出函数名，或用数值指定导出函数序号  
调用约定可省略,默认为stdcall  
this指针为可选参数，指定该参数以后在调用时可省略首参数

### dllModuleObject.api(函数地址,函数原型,调用约定,this指针) <a id="dllModuleObject.api" href="#dllModuleObject.api">&#x23;</a>
如果模块是当前进程,  
参数@1可用指针或数值指定原生函数的内存地址,  
返回值为原生函数对象（ cdata 类型 ），  

调用约定可省略,默认为stdcall  
this指针为可选参数，指定该参数以后在调用时可省略首参数

### dllModuleObject.api(导出符号名) <a id="dllModuleObject.api" href="#dllModuleObject.api">&#x23;</a>
仅指定一个参数时，  
直接返回导出符号指针而非返回原生函数对象。  
不会对参数 @1 自动添加或移除 A,W 尾标，  
而是精确匹配导出符号名。  

此操作不会增加DLL的引用计数,在使用导出符号指针时DLL变量应在生存周期内

### dllModuleObject.gethandle() <a id="dllModuleObject.gethandle" href="#dllModuleObject.gethandle">&#x23;</a>
返回模块句柄

## rawNumberObject 成员列表 <a id="rawNumberObject" href="#rawNumberObject">&#x23;</a>

### rawNumberObject.value <a id="rawNumberObject.value" href="#rawNumberObject.value">&#x23;</a>
对象存储的数值
