VarSetStrCapacity

增加变量的容量或释放其内存. 一般情况下不需要, 但可以与 DllCallSendMessage 一起使用, 或者优化重复连接.

GrantedCapacity := VarSetStrCapacity(&TargetVar , RequestedCapacity)

参数

&TargetVar

类型: VarRef

变量的引用. 例如: VarSetStrCapacity(&MyVar, 1000). 这也可以是动态变量, 例如 Array%i% 或是函数的 ByRef 参数.

RequestedCapacity

类型: 整数

如果省略, 则函数将返回变量当前的容量且不会改变其的内容. 否则, 变量中的所有内容将会丢弃(变量被置空).

指定 RequestedCapacity 为调整后变量所能容纳的字节数. RequestedCapacity 不包括内部零终止符. 例如, 指定 1 将允许变量在其内部结束符之外最多容纳一个字符. 注意: 如果脚本稍后给它分配一个更大的值, 变量将自动展开.

因此可以经常简单地调用此函数来确保变量占用最小的空间, 出于性能的考虑, 它只在 RequestedCapacity 为 0 的时候才会缩小变量. 换句话说, 如果变量的容量已经大于 RequestedCapacity, 它就不会被缩小(但为了保持一致性, 变量会被置空).

因此, 要显式地缩小变量, 首先请使用 VarSetStrCapacity(&Var, 0) 释放它占用的内存, 然后使用 VarSetStrCapacity(&Var, NewCapacity) -- 或者简单地让它自动按需从零扩展.

出于性能考虑, 要释放一个原来容量小于 64 字符的变量可能会没有效果, 因为它的内存是永久类型的. 在这种情况下, 会返回当前容量, 而不是 0.

出于性能考虑, 容量小于 4096 字节的变量的内存不能通过赋值空字符串的方法来释放(例如 Var := ""). 然而, VarSetStrCapacity(&Var, 0) 可释放它.

RequestedCapacity 指定 -1, 将变量内部存储的字符串长度更新为其当前内容的长度. 这在字符串被间接改变的情况下很有用, 比如通过 DllCallSendMessage 传递其地址. 在这种模式下, VarSetStrCapacity 返回的是长度而不是容量.

返回值

类型: 整数

该函数返回 TargetVar 现在可以容纳的字符数, 该字符数将大于或等于 RequestedCapacity.

失败

在以下任何一种情况下都会抛出异常:

备注

Buffer 对象在处理二进制数据, 结构体, DllCall 和类似的东西时, 提供了卓越的清晰度和灵活性. 例如, Buffer 对象可以分配给一个属性或数组元素, 或者传递给一个函数或从一个函数返回, 而不需要复制其内容.

在通过渐进式连接的方式构建一个字符串时, 可以使用这个函数来提高性能. 这是因为当你对字符串的最终长度有一定了解时, 可以避免多次自动调整大小. 在这种情况下, RequestedCapacity 不需要太准确: 如果容量太小, 性能仍然会得到提高, 当容量用完后, 变量将开始自动扩展. 如果容量过大, 则会浪费部分内存, 但只是暂时的, 因为所有的内存都可以在操作后通过 VarSetStrCapacity(&Var, 0)Var := "" 来释放.

Buffer 对象, DllCall, NumPut, NumGet

示例

通过确保 MyVar 有足够的工作空间来优化.

VarSetStrCapacity(&MyVar, 5120000)  ; ~10 MB
Loop
{
    ; ...
    MyVar .= StringToConcatenate
    ; ...
}

使用一个变量通过 DllCall 从外部函数接收一个字符串. (注意, 使用 Buffer 对象可能是首选; 尤其是在处理非 Unicode 字符串时.)

max_chars := 10

Loop 2
{
    ; 分配用于 DllCall 的空间.
    VarSetStrCapacity(&buf, max_chars)

    if (A_Index = 1)
        ; 通过 DllCall 间接修改变量.
        DllCall("wsprintf", "Ptr", StrPtr(buf), "Str", "0x%08x", "UInt", 4919, "CDecl")
    else
        ; 使用 "str" 来自动更新长度:
        DllCall("wsprintf", "Str", buf, "Str", "0x%08x", "UInt", 4919, "CDecl")

    ; 连接字符串以演示为什么需要更新长度:
    wrong_str := buf . "<end>"
    wrong_len := StrLen(buf)

    ; 更新变量的长度.
    VarSetStrCapacity(&buf, -1)

    right_str := buf . "<end>"
    right_len := StrLen(buf)

    MsgBox
    (
    "Before updating
      String: " wrong_str "
      Length: " wrong_len "

    After updating
      String: " right_str "
      Length: " right_len
    )
}