Ich hab mal wieder ein ganz banales Problem: ich will einen Bereich in einen anderen kopieren. Dabei ist der Zielbereich großer als der Quellbereich und jener soll auch nicht an den Anfang kopiert werden. Gibts da profaneigene Mittel oder muss ich auf APIs zurückgreifen? Ich hab in der Hilfe nichts gefunden. APIs sind kein Problem, es wäre mir aber lieber das mit hauseigenen Mitteln zu lösen.
Bereich in Bereich kopieren
-
-
-
Bei den Bereichs-Funktionen/Befehlen hast du doch das Offset :
Also so :Code
Alles anzeigenDeclare Memory bereich, bereich1, bereich2 Cls Dim bereich, 100 Dim bereich1, 4 Dim bereich2, 15 Long bereich1, 0 = 100 String bereich2, 0 = "Hello World !" Long bereich, 10 = Long(bereich1, 0) String bereich, 20 = String$(bereich2, 0) Print Long(bereich, 10) Print String$(bereich, 20) Waitkey
An 11. Stelle steht dann die 100 und ab der 21. Stelle der String.
Außerdem kann man ja auch noch mit Strukturen, Unions und Arrays
von Bereichen arbeiten. Das geht evtl. etwas leichter.Oder meinst du jetzt was ganz anderes ?
-
Naja, ist String$() auch geeignet wenn der Bereich andere Daten enthält?
Ich hätte sonst RtlMoveMemory oder RtlCopyMemory oder wie die API heißt genommen. Oder auch Ltr..., falls das schneller ist.
-
Lange Strings können jedes Zeichen, auch ein Null-Byte enthalten.
Gruß Volkmar
-
Ja ich weiß, aber ich könnte mir vorstellen, dass die Geschwindigkeit drunter leidet. Soweit ich weiß sind Operationen mit Strings recht langsam. Ich glaube ich jutze einfach die API, das ist schnell gemacht.
Danke für die Mühe.
-
Ich hab grad geschaut, die API CopyMemory kopiert einen Bereich in einen anderen, aber das geht nicht mit Offset. Weiß jemand wie das geht?
-
Ja, das weiß jemand.
-
Und möchtest du mich an deiner Weisheit teilhaben lassen?
-
Ach so, das war ernst gemeint....
CopyMemory ist mit XProfan so nicht ohne weiteres nutzbar. Was du stattdessen nutzen solltest, ist RtkMoveMemory.Remarks
This function is defined as the RtlCopyMemory function. Its implementation is provided inline. For more information, see WinBase.h and WinNT.h.
If the source and destination blocks overlap, the results are undefined. For overlapped blocks, use the MoveMemory function.Remarks
This function is defined as the RtlMoveMemory function. Its implementation is provided inline. For more information, see WinBase.h and Winnt.h.Die Adresse einer Bereichvariablen ist Variable#. Will du den Bereich 4 Bytes ab dem Offset haben, ist das Variable# + 4.
-
Ja, das weiß jemand.
Vergib mir den kleinen Spaß. Ich war da nur mit dem Handy unterwegs und konnte nicht anderes schreiben.
-
Die Bereiche überlappen sich nicht, wo ist da der unterschied zwischen Copy und Move?
Außerdem hatte ich nicht damit gerechnet zur Adresse des Bereichs einfach was zu addieren. Das erschien nur zu einfach. -
Der Unterschied ist vor allem, dass CopyMemory in keiner mit Namen benannten API als Befehl vorkommt. RtlMoveMemory kennt aber die NTDLL.DLL.
MoveMemory überschreibt auch Bereiche, die vorher noch von der Quelle belegt waren, wenn das nötig ist. -
HM, ok. Macht ja dann eh keinen Unterschied.
-
Wenn du innerhalb einer Bereichsvariablen Sachen kopieren willst, dann macht das einen großen Unterschied.
-
Jo, ich weiß. Da ist auch die Richtung entscheidend. Aber hab ja geschrieben, dass es 2 Bereiche sind. Da ists eigentlich egal.
-
Code
Alles anzeigen$H "C:\XProfan\Include\Windows.ph" ' ************************************* ' bool = Move_Mem( pointer Ziel, Quelle [, long Anzahl] ) ' Speicherinhalte kopieren ' Der angegebene Quellbereich wird in den Zielbereich kopiert. Proc Move_Mem Declare long PC PC = %PCount Declare pointer Ziel, Quelle, long zLen, qLen, Anzahl If PC = 2 Parameters pointer Ziel2, Quelle2 Ziel = Ziel2 Quelle = Quelle2 Else Parameters pointer Ziel3, Quelle3, long Anzahl3 Ziel = Ziel3 Quelle = Quelle3 Anzahl = Anzahl3 EndIf Case (Ziel = 0) or (Quelle = 0) : Return 0 zLen = SizeOf_Mem( Ziel ) qLen = SizeOf_Mem( Quelle ) Case zLen < qLen : qLen = zLen CaseNot qLen : Return 0 CaseNot Between(Anzahl, 1, qLen) : Anzahl = qLen ~MoveMemory( Ziel, Quelle, Anzahl ) Return 1 EndProc ' ************************************* ' long SizeOf_Mem( long pMem ) ' Größe des belegten Speichers ermitteln ' Ermittelt die Speichergröße auf die der Speicherzeiger zeigt. ' Liefert die Größe des Bereiches zurück. Proc SizeOf_Mem Parameters pointer pMem Declare handle hMem Var long Size = 0 CaseNot pMem : Return 0 hMem = ~GlobalHandle( pMem ) If hMem Size = ~GlobalSize( hMem ) CaseNot Size : ~GetLastError() EndIf Return Size EndProc
Jetzt mitmachen!
Sie haben noch kein Benutzerkonto auf unserer Seite? Registrieren Sie sich kostenlos und nehmen Sie an unserer Community teil!