Seite 1 von 2
Speicherbereich
Verfasst: 30.04.2007 07:16
von H.Brill
Hallo,
hab da 3 Speicherbereiche (AllocateMemory), die ich füllen
bzw. wieder auslesen möchte.
Beispiel : ber1 -> 1000 bytes und ber2 ->500 bytes soll
in ber3 (2000 bytes) kopiert werden. Nun bräuchte ich aber
dazu den Offset, ab welcher Stelle der nächste buffer steht,
damit ich den ersten Speicherblock nicht überschreibe.
Also sowas : CopyMemory(*source, *dest, offset.l, länge.l)
Die Speicherblöcke bekomme ich von einer DLL zurück und sind
keine Strings.
Verfasst: 30.04.2007 10:16
von jear
CopyMemory(*source, *dest + offset, laenge)
Ein Pointer ist eine Variable (zur Zeit vom Typ Long) und man kann damit ganz normal rechnen!
Verfasst: 30.04.2007 11:38
von H.Brill
Programm steigt immer aus bei
CopyMemory(*source, *dest + 1000, laenge)
lasse ich hingegen das Sternchen * weg, steigt
das Programm wenigstens nicht mehr aus, scheint
aber nicht richtig in den Bereich zu schreiben.
Verfasst: 30.04.2007 12:05
von AND51
Poste doch bitte mal ein Stück Source Code, wo wir den Fehler sehen & beheben können. Das macht es leichter für uns.
> lasse ich hingegen das Sternchen * weg, steigt
das Programm wenigstens nicht mehr aus
Das klingt für mich so'n bisschen danach, dass du die Pointer falsch speicherst oder so. Ich würde Pointer an deiner Stellle immer mit Sternchen voran speichern:
*meinPointer=AllocateMemory(1024)
Aber genau kann ich/können wir das nicht sagen, weil uns dein Code fehlt.
Verfasst: 30.04.2007 13:38
von H.Brill
Habe mal hier die Procedure kopiert. Vllt. reicht dieser
Ausschnit ja. Das Prog nutzt Frank Abbings Listview.dll.
Es werden die Header-Überschriften und die eigentliche
Csv-Datei zusammen gespeichert. Scheint wirklich nur
an der CopyMemory - Funktion zu hängen, denn wenn ich
diese auskommentiere läuft es, halt ohne das richtige zu speichern.
Code: Alles auswählen
Procedure SaveCsv()
anzb.l = GetNeededMemory(LV2, 1)
bereich = AllocateMemory(anzb)
bereich2 = AllocateMemory(GetColumns(LV2) * 264)
wbytes.l = ListviewToCsv(LV2, bereich, 0, 1)
tbytes.l = HeaderToCsv(LV2, bereich2, 0, 1)
bereich3 = AllocateMemory(wbytes + tbytes)
CopyMemory(*bereich2,*bereich3, tbytes)
CopyMemory(*bereich, *bereich3 + tbytes, wbytes)
err.l = WriteFileQuick(@datei, bereich3, 0, wbytes)
If err <> 0
MessageRequester("Info !", Str(err) + " Bytes" + Chr(13) + "in " + datei + Chr(13) + "geschrieben !", #PB_MessageRequester_Ok)
Else
MessageRequester("Fehler !", "Operation fehlgeschlagen !", #PB_MessageRequester_Ok)
EndIf
FreeMemory(bereich)
FreeMemory(bereich2)
FreeMemory(bereich3)
EndProcedure
Verfasst: 30.04.2007 14:26
von jear
Code: Alles auswählen
;falsch
bereich = AllocateMemory(anzb)
CopyMemory(*bereich, *bereich3 + tbytes, wbytes)
;richtig
*bereich = AllocateMemory(anzb)
CopyMemory(*bereich, *bereich3 + tbytes, wbytes)
bereich ist eine gewöhnliche Long-Variable
und hat nichts zu tun mit dem Pointer
*bereich
BTW: Auch String$ und String.s sind zwei verschiedene Variablen!
Verfasst: 30.04.2007 16:20
von H.Brill
ja, hab ich auch schon gemacht (laut Hilfe).
Deshalb hatte ich hier ja gefragt.
Wenn ich die Speicherblöcke in separate Dateien schreibe,
funktioniert ja das ganze. Wollte mir halt nur mehrere Dateien
ersparen.
Müßte doch möglich sein, 2 oder 3 Speicherblöcke zusammen
zu friemeln und später wieder auseinander zu friemeln. Die DLL
Funktion CsvToHeader gibt mir später beim Einlesen den neuen
Offset zurück, ab dem die eigentlichen CSV-Daten stehen. Den
brauche ich, um mit CsvToListview() das LV wieder zu füllen.
Verfasst: 30.04.2007 18:01
von H.Brill
Muß es im Moment so lassen wie im unten stehenden Code.
So funktioniert es, weiß der Teufel warum. Bei
bereich1 = AllocateMemory(anzb)
bekomme ich auch eine Zahl zurück. Die DLL erwartet in den
Funktionen einen Zeiger auf einen Speicherbereich. Setze ich
ein * davor, steigt die DLL aus. Wenn ich mir die resultierende
Datei ansehe, scheint CopyMemory(ohne *) auch zu funktionieren.
Code: Alles auswählen
Procedure SaveCsv()
anzb.l = GetNeededMemory(LV2, 1)
bereich1 = AllocateMemory(anzb)
bereich2 = AllocateMemory(GetColumns(LV2) * 264)
wbytes.l = ListviewToCsv(LV2, bereich1, 0, 1)
tbytes.l = HeaderToCsv(LV2, bereich2, 0, 1)
bereich3 = AllocateMemory(wbytes + tbytes)
CopyMemory(bereich2,bereich3, tbytes)
CopyMemory(bereich1, bereich3 + tbytes, wbytes)
err.l = WriteFileQuick(@datei, bereich3, 0, wbytes + tbytes)
If err <> 0
MessageRequester("Info !", Str(err) + " Bytes" + Chr(13) + "in " + datei + Chr(13) + "geschrieben !", #PB_MessageRequester_Ok)
Else
MessageRequester("Fehler !", "Operation fehlgeschlagen !", #PB_MessageRequester_Ok)
EndIf
FreeMemory(*bereich1)
FreeMemory(*bereich2)
FreeMemory(*bereich3)
EndProcedure
Verfasst: 30.04.2007 18:18
von ts-soft
Ich verstehe den Code nicht?
Die Daten stehen im Speicher (den die DLL angelegt hat)
Aus welchem Grund sollen die nun hintereinander stehen?
Willst sie speichern? WriteData(0, block1, laenge) : writedata(0, block2,
laenge) usw.
Ansonsten einen Memoryblock anlegen, der alle 3 aufnimmt, und dann mit
Offset da rein kopieren. Ob Du * nutzt oder nicht interessiert niemanden,
ist nur leserlicher. Obwohl einen Sinn sehe ich eigentlich nicht darin das
zusammen zu kopieren

Verfasst: 30.04.2007 18:53
von H.Brill
Nee, die DLL - Funktionen legen gar nix an Speicher an. Das muß ich
schon selber machen. Die schreiben nur Daten da rein.
zu 2. Die DLL schreibt mit WriteFileQuick() einen Speicherblock auf
Platte. Wenn ich die Speicherblöcke zusammenfüge, kann ich die
Spaltenüberschriften und die reinen Daten in einer einzigen Datei
speichern. CsvToHeader() gibt mir nach ReadFileQuick() den
Offset, wo die reinen Daten anfangen, zurück. Ab dann kann ich
mir einen Speicherblock reservieren (Dateilänge - Offset) und
mit CsvToListview() die Daten ins Listview füllen.