缓冲对象

class Buffer extends Object

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

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

BufferObj := Buffer(ByteCount)

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

class ClipboardAll extends Buffer

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

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

目录

类缓冲对象

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

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

静态方法

Call

创建新的缓冲对象.

BufferObj := Buffer(ByteCount, FillByte)
BufferObj := Buffer.Call(ByteCount, FillByte)

参数

ByteCount

类型: 整数

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

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

FillByte

类型: 整数

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

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

返回值

类型: Object

方法或函数返回一个 Buffer 对象.

备注

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

参数是由 __New 定义的.

方法

__New

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

BufferObj.__New(ByteCount, FillByte)

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

指定 ByteCount 来分配, 重新分配或释放缓冲. 这等同于给 Size 赋值.

指定 FillByte 用给定的数字字节值填充缓冲, 覆盖任何现有内容.

如果两个参数都省略, 则此方法没有效果.

属性

Ptr

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

CurrentPtr := BufferObj.Ptr

CurrentPtr 是一个代表缓冲当前内存地址的整数. 当释放或重新分配给缓冲时, 此地址将变为无效. 不能使用无效地址. 在缓冲对象的引用计数达到零之前, 缓冲不会被释放, 但是当它的大小更改时, 会重新分配缓冲.

Size

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

CurrentByteCount := BufferObj.Size
BufferObj.Size := NewByteCount

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

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

CurrentByteCount 总是它被赋予的确切值, 无论是由 __New 还是由以前的赋值.

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

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

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

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")