VarSetCapacity()

Vergrößert die Aufnahmekapazität einer Variable oder gibt deren Speicher frei. Normalerweise ist das nur bei ungewöhnlichen Fällen wie DllCall() notwendig.

GewährteKapazität := VarSetCapacity(ZielVar , GewünschteKapazität, FüllByte)

Parameter

ZielVar

Eine Variablenreferenz. Zum Beispiel: VarSetCapacity(MeineVar, 1000). Das kann auch eine dynamische Variable wie Array%i% oder ein ByRef-Parameter einer Funktion sein.

GewünschteKapazität

Lässt man diesen Parameter weg, wird die aktuelle Kapazität der Variable zurückgegeben und der Inhalt der Variable nicht geändert. Ansonsten geht alles verloren, was sich in der Variable befindet (die Variable wird leer gemacht).

Geben Sie für GewünschteKapazität die Anzahl der Bytes an, die die Variable nach der Anpassung enthalten soll. Bei Unicode-Zeichenketten sollte das die doppelte Länge sein. GewünschteKapazität schließt den internen Null-Terminator nicht mit ein. Zum Beispiel könnte bei einem Wert von 1 die Variable, neben ihrem internen Terminator, bis zu einem Byte enthalten. Hinweis: Die Variable wird automatisch erweitert, wenn ihr später vom Skript ein größerer Wert zugewiesen wird.

Da diese Funktion oft nur aufgerufen wird, um eine bestimmte Mindestkapazität für die Variable sicherzustellen, wird die Funktion die Variable aus Leistungsgründen erst verkleinern, wenn GewünschteKapazität 0 ist. Mit anderen Worten: Wenn die Kapazität der Variable bereits größer als GewünschteKapazität ist, wird sie nicht reduziert (allerdings wird die Variable aus Konsistenzgründen weiterhin leer gemacht).

Zum expliziten Verkleinern einer Variable ist es daher erforderlich, erst ihr Speicher mit VarSetCapacity(Var, 0) freizugeben und dann VarSetCapacity(Var, NeueKapazität) zu verwenden -- oder lassen Sie die Variable einfach bei Bedarf automatisch von Null aus erweitern.

Aus Leistungsgründen wird eine Variable mit einer ursprünglichen Kapazität von weniger als 64 Zeichen (128 Bytes in Unicode-Builds) in der Regel nicht freigegeben, da ihr Speicher permanenter Natur ist. In diesem Fall wird die aktuelle Kapazität statt 0 zurückgegeben.

Aus Leistungsgründen kann der Speicher einer Variable mit einer Kapazität von weniger als 4096 Bytes nicht durch Zuweisen einer leeren Zeichenkette (z. B. Var := "") freigegeben werden. Allerdings kann VarSetCapacity(Var, 0) die Variable freigeben.

[v1.0.44.03+]: Geben Sie -1 für GewünschteKapazität an, um die intern-gespeicherte Zeichenkettenlänge der Variable auf die Länge des aktuellen Inhalts zu aktualisieren. Diese Methode ist in Situationen nützlich, wo die Variable indirekt geändert wurde, z. B. beim Übergeben ihrer Adresse via DllCall(). In diesem Modus gibt VarSetCapacity() nicht die Kapazität, sondern die Länge in Bytes zurück.

FüllByte

Dieser Parameter wird normalerweise weggelassen, um zu verhindern, dass der Speicher der Zielvariable initialisiert wird (stattdessen wird die Variable einfach leer gemacht, wie oben beschrieben). Ansonsten kann eine Zahl zwischen 0 und 255 angegeben werden. Jedes Byte im Speicherbereich der Zielvariable (ihre aktuelle Kapazität, die größer als GewünschteKapazität sein kann) wird auf diese Zahl gesetzt. 0 ist dabei der am häufigsten benutzte Wert, der in Situationen nützlich ist, wo die Variable rohe Binärdaten enthalten wird, wie z. B. eine DllCall-Struktur.

Rückgabewert

Diese Funktion gibt die Anzahl an Bytes zurück, die die Variable nun enthalten kann und größer gleich GewünschteKapazität sein wird. Wenn ZielVar keine gültige Variable ist (z. B. direkt geschriebene Zeichenkette oder Zahl), wird eine 0 zurückgegeben. Wenn das System nicht genügend Speicher hat, um die Veränderung vorzunehmen (sehr selten), wird ein Fehlerdialogfenster angezeigt und die aktuelle Kapazität zurückgegeben - dieses Verhalten wird wahrscheinlich in einer zukünftigen Version geändert.

Bemerkungen

Diese Funktion ist nicht nur für DllCall() nützlich, sondern kann auch die Leistung beim Verketten von Zeichenketten erhöhen. Diese Methode verhindert mehrere automatische Größenanpassungen, sofern Ihnen die finale Länge der Zeichenkette bekannt ist. In so einem Fall muss GewünschteKapazität nicht genau sein: Der Leistungsgewinn gilt auch dann noch, wenn die Kapazität zu niedrig ist, außerdem beginnt die Variable sich automatisch zu erweitern, wenn die Kapazität erschöpft ist. Bei einer zu hohen Kapazität ist ein Teil des Speichers verschwendet, aber nur vorübergehend, da der gesamte Speicher nach der Operation mithilfe von VarSetCapacity(Var, 0) oder Var := "" wieder freigegeben werden kann.

#MaxMem limitiert nur die automatische Erweiterung, die eine Variable selbst durchführt. Sie hat keinen Einfluss auf VarSetCapacity.

DllCall(), #MaxMem, NumPut(), NumGet()

Beispiele

Stellt sicher, dass MeineVar genügend Spielraum hat.

VarSetCapacity(MeineVar, 10240000)  ; ~10 MB
Loop
{
    ; ...
    MeineVar .= ZuVerkettendeZkette
    ; ...
}

Verwenden Sie eine Variable, um eine Zeichenkette via DllCall() von einer externen Funktion abzurufen.

; Berechnet den erforderlichen Pufferspeicher für eine Zeichenkette.
bytes_per_char := A_IsUnicode ? 2 : 1
max_chars := 500
max_bytes := max_chars * bytes_per_char

Loop 2
{
    ; Reserviert Speicher für DllCall.
    VarSetCapacity(buf, max_bytes)

    if (A_Index = 1)
        ; Ändert die Variable indirekt via DllCall.
        DllCall("wsprintf", "Ptr", &buf, "Str", "0x%08x", "UInt", 4919)
    else
        ; Mit "str" kann die Länge automatisch aktualisiert werden:
        DllCall("wsprintf", "Str", buf, "Str", "0x%08x", "UInt", 4919)

    ; Verkettet eine Zeichenkette, um zu zeigen, warum die Länge aktualisiert werden muss:
    wrong_str := buf . "<end>"
    wrong_len := StrLen(buf)

    ; Aktualisiert die Länge der Variable.
    VarSetCapacity(buf, -1)

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

    MsgBox,
    (
    Vor der Aktualisierung
      Zeichenkette: %wrong_str%
      Länge: %wrong_len%

    Nach der Aktualisierung
      Zeichenkette: %right_str%
      Länge: %right_len%
    )
}