Procedure mit ByRef-Übergabe

Fragen und Bugreports zur PureBasic 4.0-Beta.
Benutzeravatar
Karl
Beiträge: 520
Registriert: 21.07.2005 13:57
Wohnort: zu Hause

Procedure mit ByRef-Übergabe

Beitrag von Karl »

Ist das unter PB 4 möglich bzw. wird das möglich sein?

Das Hantieren mit Strukturen ist etwas lästig.

Gruß Karl
The Kopyright Liberation Front also known as the justified ancients of Mumu!
PB 5.X
Benutzeravatar
Deeem2031
Beiträge: 1232
Registriert: 29.08.2004 00:16
Wohnort: Vorm Computer
Kontaktdaten:

Beitrag von Deeem2031 »

Code: Alles auswählen

Procedure p(*l.long)
  *l\l = 3456
EndProcedure

a = 1234
p(@a)
Debug a
Bild
[url=irc://irc.freenode.org/##purebasic.de]irc://irc.freenode.org/##purebasic.de[/url]
Benutzeravatar
uweb
Beiträge: 461
Registriert: 13.07.2005 08:39

Beitrag von uweb »

Ich habe ein ähnliches Problem :

Ich will nicht nur ggf. per Default-Wert aus einer Preference-Datei lesen, sondern sie ggf. auch ergänzen.
Damit will ich sicher stellen, daß der Anwender die Default-Werte nachvollziehen kann.

Die Idee war alle entsprechenden Variablen mit einem Default-Wert zu initialisieren der sich von dem Default-Wert in der Preference-Datei unterscheidet (vorangestelltes "*").
Wenn also z.B.
"*XY-Server" der Rückgabewert von ReadPreferenceString("ServerName", "*XY-Server") ist weis ich, daß der Eintrag fehlt.
Wenn aber "XY-Server" der Rückgabewert ist weis ich das mit Standardwerten gearbeitet wird.
Bei einem anderen Rückgabewert weis ich, daß es eine individuelle Einstellung ist.

Code: Alles auswählen

Global ServerFolder.s=Space(255)
GetCurrentDirectory_(255,@ServerFolder)
If Right(ServerFolder,1)<>"\"
  ServerFolder+"\"
EndIf


Global ServerName.s     ="*XY-Server"
Global Port.s           ="*80"
Global BufferSizeSize.s ="*16777216"

Global WebFolder.s      ="*www"
Global HomeFile.s       ="*index.htm"
Global ErrorFile.s      ="*404.htm"
Global MimeFile.s       ="*mime.txt"

Global NotOpen.s        ="*Couldn't open "
Global NotCreate.s      ="*Couldn't create "
Global InFolder.s       ="* in Folder "

Procedure.l ReadKey(*Variable.s, Keyword.s)
  DefaultValue.s = *Variable
  Debug (DefaultValue)
  Debug (ReadPreferenceString(Keyword, DefaultValue))
  *Variable = ReadPreferenceString(Keyword, DefaultValue)
  If Left(*Variable, 1) = "*"
    ProcedureReturn 1
  EndIf
  ProcedureReturn 0
EndProcedure

Procedure.l ReadINI()
  FileResult = OpenPreferences("server.ini")
  If FileResult
    KeyError=0
    Debug ("ServerName vor : "+ServerName)
    KeyError=KeyError+ReadKey(@ServerName, "ServerName")
    Debug ("ServerName nach : "+ServerName)
    KeyError=KeyError+ReadKey(@Port, "Port")
    KeyError=KeyError+ReadKey(@BufferSizeSize, "BufferSizeSize")
    KeyError=KeyError+ReadKey(@WebFolder, "WebFolder")
    KeyError=KeyError+ReadKey(@HomeFile, "HomeFile")
    KeyError=KeyError+ReadKey(@ErrorFile, "ErrorFile")
    KeyError=KeyError+ReadKey(@MimeFile, "MimeFile")
    KeyError=KeyError+ReadKey(@NotOpen, "NotOpen")
    KeyError=KeyError+ReadKey(@NotCreate, "NotCreate")
    KeyError=KeyError+ReadKey(@InFolder, "InFolder")
    Debug ("KeyError : "+Str(KeyError))
  Else
    Debug ("FileResult : "+Str(FileResult))
    ;WriteINI()
  EndIf
  ClosePreferences()
  ProcedureReturn 0
EndProcedure

ReadINI()
edit :
Mein 1. Problem - wie ich den String-Wert des String-Pointers auslesen soll habe ich gelöst.
Aber, jetzt frage ich mich weshalb der Inhalt nach ReadKey() nicht stimmt.

2. edit :
- Debug ("d : "+ServerName)
Hier wird es jetzt richtig witzig :

Code: Alles auswählen

Procedure.l ReadKey(*Variable.s, Keyword.s)
  DefaultValue.s = *Variable
  Debug ("a : "+DefaultValue)
  Debug ("b : "+ReadPreferenceString(Keyword, DefaultValue))
  *Variable = ReadPreferenceString(Keyword, DefaultValue)
  Debug ("c : "+*Variable)
  Debug ("d : "+ServerName)
  If Left(*Variable, 1) = "*"
    ProcedureReturn 1
  EndIf
  ProcedureReturn 0
EndProcedure
3.edit :
Wenn ich meinen Flüchtigkeitsfehler korrigiere
(BufferSize statt BufferSizeSize
- Variablenname nun nicht mehr länger als der von ServerName)
erhalte ich hier auch den Variablennamen.

4.edit
Mit meiner Technik (wenig Wissen, einiges Ahnen, viel Probieren)
bin ich wieder mal nicht weiter gekommen.
Also blieb mir gar nichts anderes übrig, als meine Standard-Strategie
für nicht lösbare Probleme anzuwenden : Problem umgehen !

Im Ergebnis scheint es mir sogar eleganter, da ich nun ggf. direkt beim
Lesen schreibe. Ursprünglich hatte ich vor das in einem 2. Schritt zu tun.

Unabhängig davon wäre es nett wenn mir jemand sagen könnte
ob das Problem von oben ein Fehler in der Beta oder mein Fehler war.
Bei letzterem wäre die richtige Codierung natürlich toll.

Code: Alles auswählen

Global ServerFolder.s=Space(255)
GetCurrentDirectory_(255,@ServerFolder)
If Right(ServerFolder,1)<>"\"
  ServerFolder+"\"
EndIf

Global ServerName.s ="*XY-Server"
Global Port.s       ="*80"
Global BufferSize.s ="*16777216"

Global WebFolder.s  ="*www"
Global HomeFile.s   ="*index.htm"
Global ErrorFile.s  ="*404.htm"
Global MimeFile.s   ="*mime.txt"

Global NotOpen.s    ="*Couldn't open "
Global NotCreate.s  ="*Couldn't create "
Global InFolder.s   ="* in Folder "

Procedure.s ReadKey(Keyword.s,Value.s)
  Value=ReadPreferenceString(Keyword,Value)
  If Left(Value, 1) = "*"
    Value=Right(Value, Len(Value)-1)
    WritePreferenceString(Keyword, Value)
  EndIf
  ProcedureReturn Value
EndProcedure

Procedure.l ReadINI()
  If FileSize("server.ini") <> -2
    OpenPreferences("server.ini")
    ServerName=ReadKey("ServerName",ServerName)
    Port=ReadKey("Port",Port)
    BufferSize=ReadKey("BufferSize",BufferSize)
    WebFolder=ReadKey("WebFolder",WebFolder)
    HomeFile=ReadKey("HomeFile",HomeFile)
    ErrorFile=ReadKey("ErrorFile",ErrorFile)
    MimeFile=ReadKey("MimeFile",MimeFile)
    NotOpen=ReadKey("NotOpen",NotOpen)
    NotCreate=ReadKey("NotCreate",NotCreate)
    InFolder=ReadKey("InFolder",InFolder)
    ClosePreferences()
  Else
    MessageRequester("Error","Couldn't create server.ini in Folder "+ServerFolder+" .")
  EndIf
  ProcedureReturn 0
EndProcedure

ReadINI()
P.S.
Noch einfacher und universeller wäre :

Code: Alles auswählen

Procedure.s ReadKey(Keyword.s,Value.s)
  Value="*"+Value
  Value=ReadPreferenceString(Keyword,Value)
  If Left(Value, 1) = "*"
    Value=Right(Value, Len(Value)-1)
    WritePreferenceString(Keyword, Value)
  EndIf
  ProcedureReturn Value
EndProcedure
In_Go
Beiträge: 20
Registriert: 06.02.2006 23:46
Wohnort: Eschau, Spessart

Beitrag von In_Go »

Hallo Karl!
Ich habe mir mal die Mühe gemacht und alle (?) Möglichkeiten einer Übergabe von Variablen ByRef zusammen gestellt
Ist das Dir eine Hilfe ?

Code: Alles auswählen

;Beispiel für Syntax Variablenübergabe ByReference
; Art                               Declaration       Aufruf              Procedurekopf

;Array 1 Dimension                  Name(x(1))        Name(y(1))          Name(z(1))
;Array 2 Dimensionen                Name(x(2))        Name(y(2))          Name(z(2))
;Structurvariable                   Name(*x.struc)    Name(*y.struc)      Name(*z.struc)
;Array Strukturvariable 1 Dimension Name(x.struc(1))  Name(y.struc(1))    Name(z.struc(1))
;Array Strukturvariable 2 Dimension Name(x.struc(2))  Name(y.struc(2))    Name(z.struc(2))
;Liste                              Name(x())         Name(y())           Name(z())
;Structure Liste                    Name(x.struc())   Name(y())           Name(z.struc()) 


Dim EindimensionalArray.l(4) : EindimensionalArray.l(2)=2 : EindimensionalArray.l(3) = 3
Declare TauscheEindimensionalArray(a.l(1)) :TauscheEindimensionalArray(EindimensionalArray.l())
Debug "EindimensionalesArray Sollte 3,2 sein: "+Str(EindimensionalArray.l(2))+","+Str(EindimensionalArray.l(3))
Procedure TauscheEindimensionalArray(eindim.l(1))
  eindim.l(3)=2:eindim.l(2)=3
EndProcedure

Dim ZweidimensionalArray.l(4,4) : ZweidimensionalArray.l(2,2)=2 : ZweidimensionalArray.l(3,3) = 3
Declare TauscheZweidimensionalArray(a.l(2)) :TauscheZweidimensionalArray(ZweidimensionalArray.l())
Debug "ZweidimensionalesArray Sollte 3,2 sein: "+Str(ZweidimensionalArray.l(2,2))+","+Str(ZweidimensionalArray.l(3,3))
Procedure TauscheZweidimensionalArray(zweidim.l(2))
  zweidim.l(3,3)=2:zweidim.l(2,2)=3
EndProcedure

Structure mein
  zwei.l
  drei.l
EndStructure
StrVar.mein
StrVar.mein\zwei =2 :StrVar.mein\drei=3
Declare TauscheStrukturVariable(*sv.mein) :  TauscheStrukturVariable(StrVar.mein) 
Debug "StruktureVariable Sollte 3,2 sein: "+Str(StrVar.mein\zwei)+","+Str(StrVar.mein\drei)
Procedure TauscheStrukturvariable(*st.mein)
  *st.mein\drei =2 :*st.mein\zwei= 3
EndProcedure

Dim StrVarArray.mein(4)
StrVarArray.mein(2)\zwei =2 :StrVarArray.mein(3)\drei=3
Declare TauscheStrukturVariableArray(sv.mein(1)) 
  TauscheStrukturVariableArray(StrVarArray()) 
Debug "StruktureVariableArray Sollte 3,2 sein: "+Str(StrVarArray.mein(2)\zwei)+","+Str(StrVarArray.mein(3)\drei)
Procedure TauscheStrukturvariableArray(star.mein(1))
  star.mein(3)\drei =2 :star.mein(2)\zwei= 3
EndProcedure

Dim StrVarArrayZwei.mein(4,4)
StrVarArrayZwei.mein(2,2)\zwei =2 :StrVarArrayZwei.mein(3,3)\drei=3
Declare TauscheStrukturVariableArrayZwei(svz.mein(2)) 
TauscheStrukturVariableArrayZwei(StrVarArrayZwei()) 
Debug "StruktureVariableArrayZweidimensinal Sollte 3,2 sein: "+Str(StrVarArrayZwei.mein(2,2)\zwei)+","+Str(StrVarArrayZwei.mein(3,3)\drei)
Procedure TauscheStrukturvariableArrayZwei(starZ.mein(2))
  starZ.mein(3,3)\drei =2 :starZ.mein(2,2)\zwei= 3
EndProcedure


NewList Liste.l() 
AddElement(liste()) :AddElement(liste()):AddElement(liste()):AddElement(liste())
SelectElement(Liste(),2):liste()=2
SelectElement(Liste(),3):liste()=3
Declare TauscheLinkedListElement(lister()) :TauscheLinkedListElement(liste())
SelectElement(Liste(),2): zwei= Liste() :SelectElement(Liste(),3):drei=liste()
Debug "LinkedList Sollte 3,2 sein: "+Str(zwei)+","+Str(drei)

Procedure TauscheLinkedListElement(meinLL())
  SelectElement(meinLL(),2) :meinLL()=3
  SelectElement(meinLL(),3) :meinLL()=2
EndProcedure

NewList StrukturListe.mein() 
AddElement(StrukturListe()) :AddElement(StrukturListe()):AddElement(StrukturListe()) :AddElement(StrukturListe())
SelectElement(StrukturListe(),2):StrukturListe()\zwei=2
SelectElement(StrukturListe(),3):StrukturListe()\drei=3
Declare TauscheStrukturLinkedListElement(listeR.mein()) 
TauscheStrukturLinkedListElement(StrukturListe())
SelectElement(StrukturListe(),2) : zwei= StrukturListe()\zwei 
SelectElement(StrukturListe(),3) : drei= StrukturListe()\drei
Debug "Structure LinkedList Sollte 3,2 sein: "+Str(zwei)+","+Str(drei)

Procedure TauscheStrukturLinkedListElement(meinLL.mein())
  SelectElement(meinLL(),2) :meinLL()\zwei=3
  SelectElement(meinLL(),3) :meinLL()\drei=2
EndProcedure

;
Shit happens: Let's try to make things better!
Gesperrt