缓冲对象

class Buffer extends Object

封装一块内存, 用于高级技术, 如 DllCall, 结构体, StrPut 和原始文件 I/O.

缓冲对象通常通过调用 Buffer() 创建, 但也可以由 FileRead 使用 "RAW" 选项返回.

BufferObj := Buffer(ByteCount)

ClipboardAll 返回缓冲的子类, 也命名为 ClipboardAll.

class ClipboardAll extends Buffer

下面使用 "BufferObj" 作为任何缓冲对象的占位符, 因为 "Buffer" 就是类本身.

除了从 Object, 继承的方法和属性外, Buffer 对象还具有以下预定义的属性:

静态方法:

属性:

方法:

类缓冲对象

一些内置函数接受缓冲对象来代替地址 - 请参阅相关部分以获取链接. 这些函数也接受具有 PtrSize 属性的任何其他对象, 但是针对原生的缓冲对象进行了优化.

在大多数情况下, 传递缓冲对象比传递地址更安全, 因为函数可以读取缓冲区大小以确保它不会尝试访问缓冲区之外的任何内存位置. 一个例外是 DllCall 调用程序之外的函数; 在这些情况下, 可能需要将缓冲区大小显式传递给函数.

静态方法

Call

创建缓冲.

BufferObj := Buffer(ByteCount, FillByte)
ByteCount

类型: 整数

要分配的字节数. 对应于 Buffer.Size.

如果省略, 将创建一个 null(零) Ptr 和零 Size 的缓冲.

FillByte

类型: 整数

指定一个 0 到 255 之间的数字, 以将缓冲中的每个字节设置为该数字..

在不需要先读取缓冲而直接写入的情况下, 通常应将其省略, 因为它的时间开销与字节数成正比. 如果省略, 则不初始化缓冲的内存; 每个字节的值是任意的..

如果无法分配内存, 例如 ByteCount 意外地大, 或者系统虚拟内存不足, 则抛出 MemoryError.

参数是由 __New 定义的.

属性

Ptr

检索缓冲区的当前内存地址.

Ptr := BufferObj.Ptr

类型: 整数

当释放或重新分配缓冲区时, 此属性返回的任何地址都将无效. 不能使用无效地址. 缓冲区在缓冲对象的引用计数达到零之前不会被释放, 但是当它的大小更改时会重新分配缓冲区.

Size

检索或设置缓冲区的大小, 以字节为单位.

ByteCount := BufferObj.Size
BufferObj.Size := ByteCount

类型: 整数

缓冲区的地址通常会随着大小的改变而改变. 如果减小大小, 则缓冲区中的数据将被截断, 但保留剩余的字节. 如果增加大小, 则保留所有数据并且任何新字节的值都是任意的(由于性能原因, 它们未初始化).

如果无法分配内存, 例如 ByteCount 意外地大, 或者系统虚拟内存不足, 则抛出 MemoryError.

这个属性总是返回它被赋予的确切值, 无论是由 __New 还是由以前的赋值.

方法

__New

分配或重新分配缓冲, 并可选择将其填充.

BufferObj.__New(ByteCount, FillByte)

这个方法的存在是为了支持 Call, 并不打算直接调用. 请参阅创建和销毁.

DllCall, NumPut, NumGet, StrPut, StrGet, File.RawRead, File.RawWrite, ClipboardAll

示例

通过 DllCall 使用 Buffer 从外部函数接收字符串.

max_chars := 11

; 为 wsprintf 的 Unicode 版本分配一个缓冲.
bufW := Buffer(max_chars*2)

; 使用 wsprintfW() 将一个 UTF-16 字符串打印到缓冲中.
DllCall("wsprintfW", "Ptr", bufW, "Str", "0x%08x", "UInt", 4919, "CDecl")

; 从 bufW 中检索字符串并显示出来.
MsgBox StrGet(bufW, "UTF-16")  ; 或者直接 StrGet(bufW).

; 分配一个缓冲区供 ANSI 版本的 wsprintf 使用.
bufA := Buffer(max_chars)

; 使用 wsprintfA() 将一个 ANSI 字符串打印到缓冲中.
DllCall("wsprintfA", "Ptr", bufA, "AStr", "0x%08x", "UInt", 4919, "CDecl")

; 从 bufA 中获取字符串(转换为本地格式), 并将其显示出来.
MsgBox StrGet(bufA, "CP0")
unixetc