Seite 1 von 1

Puffer durch zwei Prozeduren durchreichen

Verfasst: 03.01.2012 17:00
von pcfreak1201
Hallo!

Ich hätte da gerne wieder ein Problem :-/
Wahrscheinlich sehe ich den Wald vor lauter Bäumen nicht, aber wie kann ich einen lokalen Puffer

Code: Alles auswählen

*sBuffer
so durchreichen, daß er erst in der 2. Prozedur gefüllt/allociert wird:
Procedure Proc1(*sBuffer)

Struct\*s2Buffer = *sBuffer
Proc2(@Struct)

EndProcedure

Procedure Proc2(*Struct)

*Struct\*s2Buffer = AllocateMemory (lBufSize)

EndProcedure
... und ich dann lokal auf das "Ergebnis" zugreifen kann?!
Ich sehe im Debugger die Adresse von *s2Buffer und entsprechenden Inhalt, doch lokal ist die Adresse dann wieder 0,
obwohl ich Proc1 mit (@*sBuffer) aufgerufen habe. :coderselixir:

Re: Puffer durch zwei Prozeduren durchreichen

Verfasst: 03.01.2012 19:08
von ts-soft
Meinst Du sowas?

Code: Alles auswählen

Structure buffer
  *sBuffer
EndStructure

Procedure Proc2(*test.buffer)
  *test\sBuffer = AllocateMemory(100)
EndProcedure

Procedure Proc1()
  Protected test.buffer
  Proc2(@test)
  Debug MemorySize(test\sBuffer)
EndProcedure

Proc1()

Re: Puffer durch zwei Prozeduren durchreichen

Verfasst: 03.01.2012 21:15
von pcfreak1201
Uh :shock: - gemein, eine Frage mit einer Gegenfrage zu beantworten 8)
Ich glaube aber, bei Deinem Beispiel fehlt eine Ebene - mal etwas konkreter:
Ich möchte diese Funktion kapseln und ín meinem Programm unterschiedlich aufrufen:
http://forums.purebasic.com/english/vie ... p?p=217254

Code: Alles auswählen

Procedure DownloadUrl(sUrl.s, *Buffer) 
  
Define tHTTP.T_PBL_HTTP_GET_FROM_WEB
  
tHTTP\sURL = sUrl
[...]
tHTTP\lDestination = #PBL_WRITE_TO_MEMORY
HTTPGetFromWeb (@tHTTP)
*Buffer = tHTTP\DestBuffer

EndProcedure 
... und rufe dazu im Hauptprogram

Code: Alles auswählen

Protected *buffer
  DownloadUrl("http://www.purebasic.de", @*buffer)
auf, und wollte dann den HTML-Code in *buffer mittels PeekS() auslesen.

Re: Puffer durch zwei Prozeduren durchreichen

Verfasst: 03.01.2012 21:38
von jojo1541
Ich bin mir zwar nicht sicher, ob ich dein Problem verstehe, aber evtl. in etwa so?

Code: Alles auswählen

EnableExplicit

Global *TestBuf

Procedure SetBuf2(*Buffer)
  
  *Buffer = AllocateMemory(100)
  
  ProcedureReturn *Buffer
  
EndProcedure  
  
Procedure SetBuf1(*Buffer)
  
  Protected Pos.i
  
  Pos = SetBuf2(*Buffer)
  
  If Pos <> 0
    Debug "Erfolg. Pointer: " + Str(Pos)
    *TestBuf = Pos
  Else
    Debug "Erstellen des Speicherbereichs fehlgeschlagen"
  EndIf
    
  
EndProcedure

SetBuf1(*TestBuf)
Debug MemorySize(*TestBuf)

Re: Puffer durch zwei Prozeduren durchreichen

Verfasst: 03.01.2012 22:48
von Derren
*Irgendwas ist ein Pointer. Und der zeigt nunmal auf eine bestimmte Adresse im Speicher.
Du kannst nicht den gleichen Pointer in Prozeduren verwenden und erwarten dass du mit unterschiedlichen Speicherbereichen arbeiten kannst.

Entweder du benutzt CopyMemory() oder du machst dir eine Liste mit Pointern und übergibst die ItemID anstatt des Pointers an die Prozedur.

Re: Puffer durch zwei Prozeduren durchreichen

Verfasst: 03.01.2012 23:34
von pcfreak1201
Ahhh! Bäume! :o

Ok, notiere: die Adressen sind nicht dynamisch - davon war ich ausgegangen.
Jetzt wird es aber wieder unklarer:
Die ItemID kenne ich nur von den Gadgets - wenn wir das Gleiche meinen.
D.h. in meinem Fall, ich mache was?

Einen Integer-Wert anstatt einem Pointer übergeben? Oder geht das dann nur mit einer globalen Variablen?
Und was mache ich dann hieraus:

Code: Alles auswählen

*Buffer = tHTTP\DestBuffer
?
Das kann ich ja (u.U.) nicht ändern - also bleibt das auf alle Fälle ein Pointer?!

Re: Puffer durch zwei Prozeduren durchreichen

Verfasst: 04.01.2012 00:37
von Derren
So sollte es doch gehen?
Es geht ja nich um den Pointer in der Struktur, sondern um den Pointer, den du an die Proc2 übergibst.

Code: Alles auswählen

Procedure Proc1(*sBuffer)
	Protected var.Struct
	Struct\*s2Buffer = *sBuffer
	Proc2(var)
	
EndProcedure

Procedure Proc2(var)
	
	var\*s2Buffer = AllocateMemory (lBufSize)
	
EndProcedure
Evtl. muss var Shared sein, je nachdem was du vor hast

Re: Puffer durch zwei Prozeduren durchreichen

Verfasst: 04.01.2012 03:00
von jojo1541
Was heißt, die Speicheradressen sind nicht dynamisch... Der Pointer kann eben nur einen Wert gleichzeitig haben. (ist ja auch nur eine Variable). Du wirst also wohl oder übel für jeden Pointer eine Variable brauchen. Oder du machst es, wie Derren gesagt hat und nimmst eine Liste in der du die Pointer speicherst. Dann suchst du dir das richtige Element der Liste und benutzt den dort gespeicherten Pointer.

Edit: Ok, keine gute Idee, einen Beitrag zu schreiben und dann vom PC wegzugehen bevor man auf absenden drückt. Es passiert in der zwischenzeit so viel. /:->

Re: Puffer durch zwei Prozeduren durchreichen

Verfasst: 04.01.2012 13:47
von pcfreak1201
Arg - macht mich nicht schwach! :freak: :?

Also ich habe ja oben mein Problem gepostet:

Code: Alles auswählen

Procedure DownloadUrl(sUrl.s, *Buffer) 
Dann sagt Derren
Du kannst nicht den gleichen Pointer in Prozeduren verwenden und erwarten dass du mit unterschiedlichen Speicherbereichen arbeiten kannst.
- OK, das erklärt, warum es nicht geht, da ja der Übergebene Pointer schon einen Wert hat, aber von der endgültigen Prozedur überschrieben werden müßte,
da hier ja erst die Zuweisung mit einem Speicherinhalt erfolgt, wenn die Datei heruntergeladen wurde.
Dann sagt Derren
So sollte es doch gehen?
Es geht ja nich um den Pointer in der Struktur, sondern um den Pointer, den du an die Proc2 übergibst.
Äh, es ist nix global, alles lokal. Das Ziel ist es, den Speicherinhalt aus dem Download in meine "Hauptprozedur" - nennen wir sie mal "Browser" - zu bekommen,
aber ich füge erst in

Code: Alles auswählen

DownloadUrl
einige Daten in die Struktur für

Code: Alles auswählen

HTTPGetFromWeb
ein.
Und da es sich wie in der Überschrift gesagt um ein Durchreichen handelt, sollte auch der Einwand von jojo
Der Pointer kann eben nur einen Wert gleichzeitig haben.
egal sein,
da es sich ja immer um den Wert des Pointers aus

Code: Alles auswählen

tHTTP\DestBuffer
handel soll, der ja in der Struktur mit

Code: Alles auswählen

*DestBuffer        ; if lDestination = #PBL_WRITE_TO_MEMORY will contain the address of the memory buffer allocated by the proc
  ; else it will contain 0
definiert ist.

... Ich habe übrigens als Workaround die UTF-8 nach ASCII-Wandlung in die Prozedur DownloadUrl gepackt. Damit funktioniert es zumindes, weil zwei unterschiedliche Puffer verwendet werden ...

Stefan :|

Re: Puffer durch zwei Prozeduren durchreichen

Verfasst: 04.01.2012 17:02
von Derren
Das Problem was du hast.
Du arbeitest nicht mit einer Variable, die eine Struktur hat, sondern du arbeitest mit dem Speicherbereich der Struktur.
Was für deine Anwendung völliger Blödsinn ist.
Du überschreibst quasi deine vorher definierte Struktur. Und jede Variable, die diese Struktur hat wird mit überschrieben.

Prozeduren können keine Strukturierten Variablen zurückgeben.
Deswegen hast du nur die Möglichkeit die strukturierte Variable, die in beiden Strukturen verwenden wird Shared zu definieren.

Vergiss mal Lokal. Du kannst ja nicht erwarten, dass du eine Lokale Variable in zwei Prozeduren verwenden kannst.

Das ist dein Problem.
Und dein Lösungsansatz sah wie folgt aus.
Anstatt eine Variable zu nutzen, schreibst du alles direkt in den Speicher.
Du hast aber nicht nur die Daten, die von Proc2 zurückgegeben werden in den Speicher geschrieben, sondern damit deine komplette Struktur überschrieben.
Das heißt der nächste Aufruf der Prozedur überschreibt wieder alles.

Also entweder du kopierst den Buffer vorher (CopyMemory()) oder du benutzt shared Variablen oder eben eine Liste.

Mach doch mal ein funktionsfähiges Beispiel.
Daran kann man es dir vielleicht besser erklären.