原生接口编程与原生类型操作支持库。
这是自动导入的内置库。
释放cdata类型内核对象,慎用.
此函数保证不会重复释放已释放的内核对象,所以参数可以是已释放的内核对象,
如果参数是cdata类型内核对象,或者参数的_topointer元方法中返回类型内核对象,则调用内核对象的_gc析构函数
传入null会忽略不执行任何操作
可用于释放cdata类型内核对象、com对象、IUnknown指针、com.interface创建的对象
不能用于释放table.gc或gcdata创建的cdata对象
分配可读写的、固定长度的内存,
返回可读写该内存的原生字节数组( buffer ),可存取各种二进制数据。
可用[]下标操作符读写 8 位无符号字节数值,可用 # 操作符取数组长度。
不支持连接操作符,支持 raw.concat,string.concat,string.join 等拼接函数。
在几乎所有字符串函数中都可以作为字符串使用。
在结构体中也可作为指针、 BYTE[]
数组的值。
在原生 API 参数中可作为内存指针、字符串、输出字符串使用。
在 COM 函数中可作为安全数组使用。
分配可读写的、固定长度的内存,
返回可读写该内存的原生字节数组( buffer ),可存取各种二进制数据。
参数可以是一个结构体、字符串、或 buffer,传入{ }返回null,
重新分配内存并复制初始值指定的数据,返回buffer对象,
buffer在多数字符串函数中都可以作为字符串使用
在API中可以作为字符串、指针、字节数组使用
在COM函数中可作为安全数组使用
buffer在json中会转换为{type="Buffer";data={} }格式的表对象,
这种表对象可作为raw.buffer的唯一参数还原为buffer对象
分配可读写的、固定长度的内存,
返回可读写该内存的原生字节数组( buffer ),可存取各种二进制数据。
参数一指定需要分配的内存大小,
,内存初始值可以用结构体、指针、buffer、或字符串指定一段内存数据,
也可用一个数值指定所有字节的初始值,不指定默认初始化所有字节为0,
如果初始值指定为字符串或buffer类型,
填充初始数据以后剩余的字节会全部初始为为0
此函数分配的内存是可读写的字节数组,可使用下标操作符读写字节值
buffer在多数字符串函数中都可以作为字符串使用
在API中可以作为字符串、指针、字节数组使用
转换参数@1指定的数值为 byte 类型数值(8位整数)包装对象,
返回对象支持 tonumber tostring 等类型转换函数。
用于调用非声明式原生 API 函数的参数,
默认传值,参数@2为 true 则用于传址参数(传数值的指针)。
用于 COM 函数参数则总是传值, COM 函数也可使用 com.byte 函数
关闭句柄资源
此函数主要用于向raw.realloc创建的[动态指针]所指内存中追加数据
二进制模式拼接字符串
文本模式拼接请使用string.concat
参数@1应为 buffer 对象,
buffer保留长度可省略,默认为0
追加长度可省略,默认为追加字符串长度
返回拼接后的有效数据长度,有效长度不会超过 buffer大小
追加数据
参数@1必须是raw.realloc创建的[动态指针]
如果内存长度不够时,此函数会自动调用raw.realloc调整内存大小
此函数返回新的[动态指针],传入的动态指针地址可能改变必须弃用
追加数据可以是字符串、buffer、动态指针、普通指针、结构体
追加长度为可选参数,如果追加数据为指针、或动态指针则必须明确指定追加长度如果
如果追加参数是字符串、或 buffer,会在尾部添加'\u0000'
(不计长度)
可选在第4个参数中指定动态调整指针内存大小时的默认增加长度,该值默认为1024
转换并返回结构体
读取内存数据到目标结构体,返回目标结构体,
参数@1可以是指针、buffer、字符串,
可选用参数@3指定在源指针上按字节单位计数的偏移位置,不指定默认为0,
如果在参数@4指定了按结构体为单位大小的偏移位置,则忽略参数@3
把结构体写入内存,返回内存指针,
参数@2可以是指针、buffer,
可选用参数@3指定在目标指针上按字节单位计数的偏移位置,不指定默认为0,
如果在参数@4指定了按结构体为单位大小的偏移位置,则忽略参数@3
转换结构体,返回目标结构体
将指针指向的内存转换为普通数组,传入空指针返回空值
数据类型参数可省略,默认为"pointer"
类型类型也可以直接传入一个声明元素类型的结构体参数
注意该函数不会检测内存溢出错误,调用该函数时必须保证数组长度是正确的值
复制内存数据
复制内存数据
参数@1允许指针,buffer类型参数,
参数@2允许使用指针,buffer,字符串,或结构体参数,
此函数不允许其他可自动转换为指针的非指针类型参数。
如果复制源或目标是buffer,字符串,或结构体等可获取内存长度的类型,
复制长度可以省略,如果未指定复制长度,并且源数据是buffer,或字符串时,
复制全部数据并且复制尾部隐藏的'\u0000'
到目标内存,如果复制目标是指针,
那么要保证复制源加上这2个字节也不会超过目标内存长度。
如果aardio能获取复制源或目标的内存长度,
那么复制长度不会超过实际检测到的内存长度,
但如果参数是指针将无法自动检测到内存长度
转换参数@1指定的数值为 double 类型数值(64位浮点数)包装对象,
返回对象支持 tonumber tostring 等类型转换函数。
用于调用非声明式原生 API 函数的参数,
默认传值,参数@2为 true 则用于传址参数(传数值的指针)。
用于 COM 函数参数则总是传值, COM 函数也可使用 com.double 函数
返回复制的系统句柄
除参数1之外,其他参数可选
默认仅在当前进程中复制句柄
复制的句柄应使用raw.closehandle释放
运行外部程序,成功返回 true。
process.execute 函数提供类似的功能,区别可参考函数源码
运行外部程序,成功返回 true。
@file 指定要运行的程序路径,其他所有参数可省略,
@param 字符串参数,可选指定启动参数。
@operation 可选用一个字符串指定执行动词,省略则使用默认动词或 "open"。
@showCmd 可选用 SW 前缀常量指定显示选项,默认为 _SW_SHOW。
@workDir 参数可选指定工作目录。
@hwnd 可选指定所有窗口句柄,默认取当前线程活动窗口
使用资源管理器(Explorer.exe)打开文件或目录。
第一个参数 @path 指定文件路径,可为空值( null )。
注意 Explorer.exe 不解析标准的命令行参数转义符,这一点与其他程序不同。
如参数 @path 尾部有双反斜杠\\
则为无效路径并打开默认目录(打开我的文档,XP系统报错)。
如参数 @path 指定为 ","或"file:" 则打开“此电脑(This PC)”。
如参数 @path 使用shell:::
前缀则可以指定特殊路径的 CLSID。
可用第二个参数 @args 或更多参数指定 Explorer.exe 命令行选项,
例如指定 "/select" 在资源管理器选择指定路径。
注意 "/n" 等选项在新系统中是无意义的,Explorer 将总是打开新窗口。
用法与string.find相同
区别是参数@1允许使用内存指针
并必须使用参数@2指定查找数据的内存长度
指定错误的指针或长度会导致内存错误,请谨慎使用此函数
使用模式串在字符串中查找子串的位置,
参数@1可以使用指针、字符串、或 buffer
无论指定任何类型,内存长度都不可省略,aardio不会检测指定的内存长度是否错误
开始位置为可选参数,默认为1,必须以字节计数,
函数返回匹配结果的起始,结束位置,以及所有捕获分组
如果有多个捕获分组,将附加为多个返回值
转换参数@1指定的数值为 float 类型数值(32位浮点数)包装对象,
返回对象支持 tonumber tostring 等类型转换函数。
用于调用非声明式原生 API 函数的参数,
默认传值,参数@2为 true 则用于传址参数(传数值的指针)。
用于 COM 函数参数则总是传值, COM 函数也可使用 com.float 函数
与 string.indexOf 类似,
但 raw.indexOf 基于二进制搜索字符串,可查找包含 '\0'
的字符串。
更重要的区别是参数 @1允许使用内存指针,
并必须使用参数 @2 指定查找数据的内存长度。
指定错误的指针或长度会导致内存错误,请谨慎使用此函数。
使用模式串在字符串中查找子串的位置,
参数@1可以使用指针、字符串、或 buffer
无论指定任何类型,内存长度都不可省略,aardio不会检测指定的内存长度是否错误
开始位置为可选参数,默认为1,必须以字节计数,
函数返回匹配结果的起始位置
转换参数@1指定的数值为 int 类型数值(32位整数)包装对象,
返回对象支持 tonumber tostring 等类型转换函数。
用于调用非声明式原生 API 函数的参数,
默认传值,参数@2为 true 则用于传址参数(传数值的指针)。
用于 COM 函数参数则总是传值, COM 函数也可使用 com.int 函数
拼接字符串或 buffer 数组,返回 buffer。
如果拼接后长度为空,此函数返回 null。
参数@1指定的数组可包含字符串或buffer,
包含 buffer 的数组只能用 raw.join 拼接,不可使用 string.join 拼接
参数 @2 可选指定一个间隔字符串。
起始索引与结束索引为可选参数,可传入负数表示自数组尾部倒计数
加载 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同样是多进程模式。
第一个参数可以是DLL路径或DLL内存数据,
载入内存DLL数据时,可使用第二个参数指定共享模块名称以启用共享模式,
如果DLL本身是库文件,则共享名称应使用库名字空间路径.
参数@3可选指定调用约定,默认为"stdcall,microsoft"
路径首字符可用斜杠表示应用程序根目录,用~加斜杠表示EXE根目录
如果~\
或~/
开头的EXE根目录路径不存在,自动转换为应用程序根目录下的路径重试,
如果DLL文件依赖同目录下的其他DLL文件,而这些DLL不在默认搜索目录顺序内时,
aardio将会调用::Kernel32.SetDllDirectory()自动修正该问题,
并在操作完成后自动恢复默认设置
转换参数@1指定的数值为 long 类型数值(64位整数)包装对象,
返回对象支持 tonumber tostring 等类型转换函数。
用于调用非声明式原生 API 函数的参数,
默认传值,参数@2为 true 则用于传址参数(传数值的指针)。
用于 COM 函数参数则总是传值, COM 函数也可使用 com.long 函数
进程主模块,默认调用约定为stdcall
与raw.module("stdcall")返回的值相同,
可用于将当前进程中的函数指针转换为aardio函数
用法与string.match相同
区别是参数@1允许使用内存指针
并必须使用参数@2指定查找数据的内存长度
指定错误的指针或长度会导致内存错误,请谨慎使用此函数
使用模式串在字符串中查找子串,
参数@1可以使用指针、字符串、或 buffer,
无论指定任何类型,内存长度都不可省略,aardio不会检测指定的内存长度是否错误
参数@3指定查找模式串。
参数@4可选,用于指定起始位置,负数表示尾部倒计数,
返回匹配字符串,如果使用了匹配分组则返回多个对应的匹配串,
返回值的顺序对应模式串中左圆括号的开始顺序
混入新的值,支持任意个混入table对象,
自动更新指针指向内存,并返回结构体对象
指定约定并返回进程主模块,
省略参数时调用约定默认为stdcall,
可用于将当前进程中的函数指针转换为aardio函数,
快速分配内存并返回[动态指针]
aardio会在[动态指针]头部倒退8个字节记录内存以及存储内容长度,
动态指针的头部结构体如下:
{
INT capacity;//分配的内存容量
INT size;//存储的数据长度
}
动态指针指向的内存尾部隐藏2个字节并放置'\u0000'
(不计入内存长度)
[动态指针]可作为普通指针使用,并可用于 raw.concat 函数快速拼接数据
使用此函数将[动态指针]的长度设为0时可释放内存
[动态指针]不会被自动回收,必须手动释放
长度指定为0则释放[动态指针],指针参数为null时忽略不报错
建议使用传入[动态指针]的变量接收空的返回值,以避免误用失效的指针变量
快速分配内存并返回指针,
可选用参数3指定分配内存中所有字节的初始值
初始值可指定所有字节的字节码,也可指定字符串、结构体
返回分配的指针,该指针可作为普通指针使用
指针不会被自动回收,必须手动释放
调整内存大小,可能返回新指针
传入指针必须弃用,返回值是新的指针必须手动释放,
可选用参数3指定分配内存中所有字节的初始值,
初始值可指定所有字节的字节码,也可指定字符串、结构体
指定初始值会重置指针记录的数据长度
如果指定的初始值为字符串或 buffer,
并且其长度超过了动态指定已分配的内存长度,
则aardio会自动截断放不下去的尾部数据。
在外部进程内创建远程调用函数
参数(进程ID或句柄,函数原型,加载DLL模块名,函数名,调用约定)
不指定调用约定时默认使用stdcall调用约定
不会在API函数名字后面自动添加或移除"A","W"编码声明后缀,
并且要注意搜索DLL时默认搜索路径包含目标EXE所在目录,而非当前EXE目录
参数(进程ID或句柄,函数原型,加载DLL模块名,函数名,调用约定)
不会在API函数名字后面自动添加或移除"A","W"编码声明后缀,
并且要注意搜索DLL时默认搜索路径包含目标EXE所在目录,而非当前EXE目录
参数(进程ID或句柄,函数原型,CALL地址,调用约定)
参数@1可以是进程ID,也可以是进程句柄(此函数不负责关闭该句柄)
注意参数@1不能指定当前进程ID或句柄,
不指定调用约定在数时默认使用stdcall调用约定
参数(进程ID或句柄,函数原型,加载DLL模块名,函数名,调用约定)
thiscall使用第一个参数指定this指针地址
不会在API函数名字后面自动添加或移除"A","W"编码声明后缀,
并且要注意搜索DLL时默认搜索路径包含目标EXE所在目录,而非当前EXE目录
复制进程内有效句柄并序列化对象
只能用于_serialize元方法,且必须kernelCall参数为真
序列化类构造函数必须支持指针参数1为指针类型句柄,参数2为true的参数
并负责在析构函数中调用 raw.closehandle 释放该句柄
返回结构体、原生类型、动态指针内存长度
参数可以是结构体、或包含类型名的字符串
参数如果是指针,则必须是raw.realloc函数创建的动态指针,
传入动态指针,返回2个值,分别为存储数据长度、分配内存总长度
传入其他来源指针,因缺少指针头信息会导致崩溃
传入null值返回0
无参数报错
转换为纯文本字符串(去掉尾部多余终结符)
参数为空返回null
如果输入参数是字符串,应当改用 string.str 函数
转换为纯文本字符串(去掉尾部多余终结符)
参数一可以是指针或buffer,其余参数可省略,偏移默认为0
参数@2为true反回字符串标记会设置UTF-16标记,否则设为UTF-8标记,
注意此函数并不会转换编码,不可指定错误的编码参数
参数为空返回null
结构体内存数据转换为文本字符串
参数@2为 true 返回字符串标记会设置 UTF-16 标记,否则设为 UTF-8 标记
注意此函数并不会转换编码,不可指定错误的编码参数
反向转换整数的大小端字节序
参数@2指定API数据类型,支持"INT","int","WORD","word",省略则默认为"INT"
64位整数请使用math.size64对象的swap函数转换
获取对象的指针,可选用参数@2指定偏移值,
所有可用于API函数 pointer 类型的对象都可以用此函数提取指针
参数不允许为数值,数值转换为指针类型应使用topointer函数
滥用此函数提取对象的原始指针在很多时候是不必要且不安全的,
可能在原对象被回收以后,仍然在错误的使用获得的指针,让程序变得不稳定。
实际上 buffer, 结构体等对象在很多函数里都可以直接作为指针使用,
这样更安全、更稳定、代码更简洁,也避免了不必要的函数调用。
此函数的作用是在运行时创建一个确定长度的原生类型数组。
也可以直接定义不指定长度的原生数组,并在运行时使用 length 属性改变长度。
示例:{ int array[] = { length = 10 } }
创建一个包含指定长度原生类型数组的结构体。
参数@1指定数组长度值,也可以指定用于初始化原生数组的 aardio 数组。
可选参数 @2 指定数组元素类型,默认为"struct",
可选参数@3指定数组字段名字,默认为"array"。
创建cdecl调用约定的原生回调函数,
应保持原生回调函数在有效作用域内,否则会自动释放,
函数返回值应当先赋值到变量而不是直接写到调用参数里,
这会导致函数未返回但原生回调函数可能已释放。
如果原生回调函数被指定为某对象的成员,在函数内部又循环引用了该对象,
这会导致无法释放资源。使用参数@3将该对象指定为owner可避免该问题
参数@2与API声明语法相同,可使用&表示输出参数,
例如C中的int *指针在aardio回调中声明为int &
有几个输出参数,就可增加相应个数的返回值用于更新输出参数值,
未返回的输出结构体参数忽略不更新传入的结构体。
回调参数声明可直接指定结构体,传入实参必须是结构体指针,
结构体声明不能再嵌套结构体,不能包含变量,
示例:raw.tocdecl(func,"int({int x;int y} &pt)")
返回值类型检测比输出参数宽松,数值,布尔值、null值可按C规则兼容转换,
返回值传结构体时必须返回不大于64位的结构体,且传值而非传址
创建 ms-fastcall 调用约定的原生回调函数
注意前两个参数不能大于32位,
应保持原生回调函数在有效作用域内,否则会自动释放,
函数返回值应当先赋值到变量而不是直接写到调用参数里,
这会导致函数未返回但原生回调函数可能已释放。
如果原生回调函数被指定为某对象的成员,在函数内部又循环引用了该对象,
这会导致无法释放资源。使用参数@3将该对象指定为owner可避免该问题
参数@2与API声明语法相同,可使用&表示输出参数,
例如C中的int *指针在aardio回调中声明为int &
有几个输出参数,就可增加相应个数的返回值用于更新输出参数值,
未返回的输出结构体参数忽略不更新传入的结构体。
回调参数声明可直接指定结构体,传入实参必须是结构体指针,
结构体声明不能再嵌套结构体,不能包含变量,
示例:raw.tocdecl(func,"int({int x;int y} &pt)")
返回值类型检测比输出参数宽松,数值,布尔值、null值可按C规则兼容转换,
返回值传结构体时必须返回不大于64位的结构体,且传值而非传址
创建stdcall调用约定的原生回调函数,
应保持原生回调函数在有效作用域内,否则会自动释放,
函数返回值应当先赋值到变量而不是直接写到调用参数里,
这会导致函数未返回但原生回调函数可能已释放。
如果原生回调函数被指定为某对象的成员,在函数内部又循环引用了该对象,
这会导致无法释放资源。使用参数@3将该对象指定为owner可避免该问题
参数@2与API声明语法相同,可使用&表示输出参数,
例如C中的int *指针在aardio回调中声明为int &
有几个输出参数,就可增加相应个数的返回值用于更新输出参数值,
未返回的输出结构体参数忽略不更新传入的结构体。
回调参数声明可直接指定结构体,传入实参必须是结构体指针,
结构体声明不能再嵌套结构体,不能包含变量,
示例:raw.tocdecl(func,"int({int x;int y} &pt)")
返回值类型检测比输出参数宽松,数值,布尔值、null值可按C规则兼容转换,
返回值传结构体时必须返回不大于64位的结构体,且传值而非传址
将结构体、指针、或 buffer 对象转换为普通字符串
参数如果是结构体不需要指定截取位置
参数如果是 buffer 类型,自动获取 buffer 长度并设为截取长度
参数如果是指针且未指定长度时,以'\0'
为终止符并设为截取长度,
转换为不包含'\0'
的文本字符串,建议改用 raw.str 函数
将指针、或 buffer 对象转换为普通字符串
start指定开始位置(省略则默认设为1),end指定结束位置,
如果未指定结束位置参数,
参数如果是buffer类型,自动获取buffer长度并设为结束位置
参数如果是指针,以'\0'
为终止符并设为结束位置
如果参数是一个包含原生数组的结构体,
返回原生类型名,以及数组字段名字。
如果是其他对象则返回 null 。
转换参数@1指定的数值为 BYTE 类型数值(8位无符号整数)包装对象,
返回对象支持 tonumber tostring 等类型转换函数。
用于调用非声明式原生 API 函数的参数,
默认传值,参数@2为 true 则用于传址参数(传数值的指针)。
用于 COM 函数参数则总是传值, COM 函数也可使用 com.ubyte 函数,
注意在原生类型中使用大写的 BYTE 类型表示8位无符号整数
转换参数@1指定的数值为 INT 类型数值(32位无符号整数)包装对象,
返回对象支持 tonumber tostring 等类型转换函数。
用于调用非声明式原生 API 函数的参数,
默认传值,参数@2为 true 则用于传址参数(传数值的指针)。
用于 COM 函数参数则总是传值, COM 函数也可使用 com.uint 函数,
注意在原生类型中使用大写的 INT 类型表示32位无符号整数
参数@1可传入数值或 math.size64 对象,
返回适用于 LONG 类型数值(64位无符号整数)的包装对象,
返回对象支持 tonumber tostring 等类型转换函数。
用于调用非声明式原生 API 函数的参数,
默认传值,参数@2为 true 则用于传址参数(传数值的指针)。
用于 COM 函数参数则总是传值, COM 函数也可使用 com.ulong 函数,
注意在原生类型中使用大写的 LONG 类型表示64位无符号整数
转换参数@1指定的数值为 WORD 类型数值(16位无符号整数)包装对象,
返回对象支持 tonumber tostring 等类型转换函数。
用于调用非声明式原生 API 函数的参数,
默认传值,参数@2为 true 则用于传址参数(传数值的指针)。
用于 COM 函数参数则总是传值, COM 函数也可使用 com.uword 函数,
注意在原生类型中使用大写的 WORD 类型表示16位无符号整数
转换参数@1指定的数值为 word 类型数值(16位整数)包装对象,
返回对象支持 tonumber tostring 等类型转换函数。
用于调用非声明式原生 API 函数的参数,
默认传值,参数@2为 true 则用于传址参数(传数值的指针)。
用于 COM 函数参数则总是传值, COM 函数也可使用 com.word 函数
可不用声明直接在此输入函数名并调用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 版本处理。
声明API函数,参数(函数名,函数原型,调用约定="stdcall,microsoft")
可选使用参数3指定调用约定,默认值为"stdcall,microsoft",
返回值为原生函数对象( cdata 类型 )
声明API函数,参数(函数名,函数原型,调用约定)
参数3使用一个字符串指定调用约定,逗号后面可选指定开发工具厂商,
返回值为原生函数对象( cdata 类型 )
声明API函数,
返回值为原生函数对象( cdata 类型 ),
参数@1也可以指定导出函数名,或用数值指定导出函数序号
调用约定可省略,默认为stdcall
this指针为可选参数,指定该参数以后在调用时可省略首参数
如果模块是当前进程,
参数@1可用指针或数值指定原生函数的内存地址,
返回值为原生函数对象( cdata 类型 ),
调用约定可省略,默认为stdcall
this指针为可选参数,指定该参数以后在调用时可省略首参数
仅指定一个参数时,
直接返回导出符号指针而非返回原生函数对象。
不会对参数 @1 自动添加或移除 A,W 尾标,
而是精确匹配导出符号名。
此操作不会增加DLL的引用计数,在使用导出符号指针时DLL变量应在生存周期内
返回模块句柄
对象存储的数值