Array als Parameter, klappt nicht?

Anfängerfragen zum Programmieren mit PureBasic.
Benutzeravatar
Blackskyliner
Beiträge: 532
Registriert: 28.07.2005 00:54
Wohnort: /home/Blackskyliner/

Array als Parameter, klappt nicht?

Beitrag von Blackskyliner »

Das ist mein code, der an kommentierter stelle den ganzen Debugger wegschießt...
Bug oder fehlverwendung des Arrays als übergabeparameter, oder liegt es doch an CallFunctionFast?

Habs bei Anfänger gepostet, da ich nicht weiß, ob es an mir oder der Sprache liegt..

Code: Alles auswählen

;---SNIP---
EnableExplicit

Structure multiDatatype
	type.l ; #PB_Integer, #PB_String, ...
	StructureUnion 
		integer.i
		long.l
		double.d
		
		float.f
		quad.q
		
		byte.b
		ascii.a
		character.c
		word.w
		unicode.u
		
		*pointer
	EndStructureUnion
	string.s
EndStructure

Structure t_dispatch
	*func
	Array Param.multiDatatype(10); max 10 parameter (one dimension)
EndStructure

Procedure DispatchMe(Array Param.multiDatatype(1)) ; one dimension expected
	Debug "x" 	; Breakpoint me and I'll crash [PB 4.50RC2 x86, Win7x64] -- Bug or programmers failure?
			; Investigation Note: I crashes, because the Debugger want to dereference the Array...
EndProcedure
;---SNIP---
;...
;---SNIP---
; Allocate and Initialize dispatch structure
Define *temp.t_dispatch = AllocateMemory(SizeOf(t_dispatch))
InitializeStructure(*temp, t_dispatch)

*temp\func = @DispatchMe()
; But now if i comment those lines out it'll work
; But then the funcion only gets a Array with the size -1, not 10
; I thinks thats the error... But don't know why...
; If i would only use a .s Array, the error won't happen in the first place
; but after dereference the Array, the program also crash...
*temp\Param(0)\type = #PB_Long
*temp\Param(0)\long = 1000
;---SNIP---
;...
;---SNIP---

; So maybe the Problem is within here...
; Can't I push the Array as a CallFunctionFast Parameter?
CallFunctionFast(*temp\func, *temp\Param())
;---SNIP---

Danke.
Blackskyliner
Keine meiner Antworten ist endgültig, es kann passieren, dass ich den so eben geposteten Beitrag noch mehrmals ändere, um Doppelposts zu umgehen.
_________________
Purebasic Windows 7 x64 & Linux (Ubuntu 10.04LTS) 4.50[x64|x86] Nutzer
_________________
Projekte: YAED - Yet another Event Dispatcher
Benutzeravatar
STARGÅTE
Kommando SG1
Beiträge: 7031
Registriert: 01.11.2005 13:34
Wohnort: Glienicke
Kontaktdaten:

Re: Array als Parameter, klappt nicht?

Beitrag von STARGÅTE »

CallFunctionFast hat geschrieben:Hinweis: Diese Funktion ist nicht sehr flexibel und kann nicht mit String/Fließkomma/Double/Quad-Variablen als Parameter bzw. Rückgabewert umgehen. Die Verwendung von Prototypen ist stattdessen sehr zu empfehlen.
Also auch keine Arrays!
Du kannst höchstens selber den Pointer für ein Array übergeben, aber nicht so wie du das gerade vorhast!
PB 6.01 ― Win 10, 21H2 ― Ryzen 9 3900X, 32 GB ― NVIDIA GeForce RTX 3080 ― Vivaldi 6.0 ― www.unionbytes.de
Aktuelles Projekt: Lizard - Skriptsprache für symbolische Berechnungen und mehr
Benutzeravatar
Blackskyliner
Beiträge: 532
Registriert: 28.07.2005 00:54
Wohnort: /home/Blackskyliner/

Re: Array als Parameter, klappt nicht?

Beitrag von Blackskyliner »

Mhm... und wie greife ich wenn ich den Pointer übergebe, dann auf die einzelnen Elemente zu? Das ich das mit Pointerarithmetik weiterschieben kann um an Element 0...9 zu kommen ist mir klar, nur nicht wie ich das dann auslese an der eig. Position, da ich ja keinen Primitiven sondern einen komplexen Datentypen benutze.

EDIT:
Habs selber gelöst :)
Danke für den Tipp.

Code: Alles auswählen

;---SNIP---
EnableExplicit

Structure multiDatatype
   type.l ; #PB_Integer, #PB_String, ...
   StructureUnion 
      integer.i
      long.l
      double.d
      
      float.f
      quad.q
      
      byte.b
      ascii.a
      character.c
      word.w
      unicode.u
      
      *pointer
   EndStructureUnion
   string.s
EndStructure

Structure t_dispatch
   *func
   Param.multiDatatype[10]; max 10 parameter
EndStructure

Procedure DispatchMe(*Param.multiDatatype)
	Debug PeekL(*Param) ;Type
	Debug PeekL(*Param+SizeOf(Long)) ; Long 
EndProcedure
;---SNIP---
;...
;---SNIP---
; Allocate and Initialize dispatch structure
Define *temp.t_dispatch = AllocateMemory(SizeOf(t_dispatch))
InitializeStructure(*temp, t_dispatch)

*temp\func = @DispatchMe()
*temp\Param[0]\type = #PB_Long
*temp\Param[0]\long = 1000
;---SNIP---
;...
;---SNIP---

CallFunctionFast(*temp\func, *temp\Param)
;---SNIP---
Keine meiner Antworten ist endgültig, es kann passieren, dass ich den so eben geposteten Beitrag noch mehrmals ändere, um Doppelposts zu umgehen.
_________________
Purebasic Windows 7 x64 & Linux (Ubuntu 10.04LTS) 4.50[x64|x86] Nutzer
_________________
Projekte: YAED - Yet another Event Dispatcher
Benutzeravatar
STARGÅTE
Kommando SG1
Beiträge: 7031
Registriert: 01.11.2005 13:34
Wohnort: Glienicke
Kontaktdaten:

Re: Array als Parameter, klappt nicht?

Beitrag von STARGÅTE »

Du kannst auch mit Strukturen arbeiten um dann noch einfach mit dem Array zu arbieten:

Code: Alles auswählen

Structure MyStruc
  Long.l
  Byte.b
  String.s
EndStructure

Structure Fake
  Field.MyStruc[0]
EndStructure

Dim MyArray.MyStruc(10)


Procedure Test(*ArrayPointer.Fake)
  ; Felderanzahl des Arrays bei -2*Integer
  Debug PeekI(*ArrayPointer-2*SizeOf(Integer))
  ; Strukturgröße des ArrayFelds bei -1*Integer
  Debug PeekI(*ArrayPointer-1*SizeOf(Integer))
  Debug "---"
  For n = 0 To 10
    Debug *ArrayPointer\Field[n]\Long
    Debug *ArrayPointer\Field[n]\String
  Next
EndProcedure

For n = 0 To 10
  MyArray(n)\Long = n
  MyArray(n)\String = Str(n)
Next

Test(MyArray())
Mit dabei sind gleich noch ein paar "geheime Daten" vor dem Array-Pointer zur Größe und Structure.
Ich weiß jedoch nicht mehr gebau ob es wirklich Integer oder Long war, das müsste mal einer mit 64Bit testen.
PB 6.01 ― Win 10, 21H2 ― Ryzen 9 3900X, 32 GB ― NVIDIA GeForce RTX 3080 ― Vivaldi 6.0 ― www.unionbytes.de
Aktuelles Projekt: Lizard - Skriptsprache für symbolische Berechnungen und mehr
Benutzeravatar
Blackskyliner
Beiträge: 532
Registriert: 28.07.2005 00:54
Wohnort: /home/Blackskyliner/

Re: Array als Parameter, klappt nicht?

Beitrag von Blackskyliner »

Da fragt man sich, warum sowas nur "dirty" möglich ist und warum es dafür keinen sauberen Weg gibt... Ich hoffe das dies irgendwann einmal der Fall sein wird... Bis dahin nutze ich den hack...
Keine meiner Antworten ist endgültig, es kann passieren, dass ich den so eben geposteten Beitrag noch mehrmals ändere, um Doppelposts zu umgehen.
_________________
Purebasic Windows 7 x64 & Linux (Ubuntu 10.04LTS) 4.50[x64|x86] Nutzer
_________________
Projekte: YAED - Yet another Event Dispatcher
Benutzeravatar
STARGÅTE
Kommando SG1
Beiträge: 7031
Registriert: 01.11.2005 13:34
Wohnort: Glienicke
Kontaktdaten:

Re: Array als Parameter, klappt nicht?

Beitrag von STARGÅTE »

wieso der saubere weg geht ja auch, nur halt nicht mit CallFunctionFast !

Sonden nur normal, mit Procedure und Prototype
PB 6.01 ― Win 10, 21H2 ― Ryzen 9 3900X, 32 GB ― NVIDIA GeForce RTX 3080 ― Vivaldi 6.0 ― www.unionbytes.de
Aktuelles Projekt: Lizard - Skriptsprache für symbolische Berechnungen und mehr
Benutzeravatar
helpy
Beiträge: 636
Registriert: 29.08.2004 13:29

Re: Array als Parameter, klappt nicht?

Beitrag von helpy »

STARGÅTE hat geschrieben:Du kannst auch mit Strukturen arbeiten um dann noch einfach mit dem Array zu arbieten ...
Ich hab' diesen Code in 4.50 laufen lassen! Als Strukturgröße des ArrayFeldes wird da 7 ausgegeben. Das stimmt aber nicht, denn die Strukturgröße von MyStruct ist 9!
Windows 10
PB Last Final / (Sometimes testing Beta versions)
Benutzeravatar
STARGÅTE
Kommando SG1
Beiträge: 7031
Registriert: 01.11.2005 13:34
Wohnort: Glienicke
Kontaktdaten:

Re: Array als Parameter, klappt nicht?

Beitrag von STARGÅTE »

jo stimmt, dann ist das wohl veraltet.
aber das mit Felderanzahl sollte stimmen.
PB 6.01 ― Win 10, 21H2 ― Ryzen 9 3900X, 32 GB ― NVIDIA GeForce RTX 3080 ― Vivaldi 6.0 ― www.unionbytes.de
Aktuelles Projekt: Lizard - Skriptsprache für symbolische Berechnungen und mehr
freak
PureBasic Team
Beiträge: 766
Registriert: 29.08.2004 00:20
Wohnort: Stuttgart

Re: Array als Parameter, klappt nicht?

Beitrag von freak »

Blackskyliner hat geschrieben:Da fragt man sich, warum sowas nur "dirty" möglich ist und warum es dafür keinen sauberen Weg gibt... Ich hoffe das dies irgendwann einmal der Fall sein wird... Bis dahin nutze ich den hack...
Den sauberen Weg gibt es: Prototypes. CallFunctionFast() ist veraltet und nur noch da für Kompatibilität.

Drei Zeilen ändern und das Ganze läuft wunderbar:

Code: Alles auswählen

;---SNIP---
EnableExplicit

Structure multiDatatype
   type.l ; #PB_Integer, #PB_String, ...
   StructureUnion
      integer.i
      long.l
      double.d
      
      float.f
      quad.q
      
      byte.b
      ascii.a
      character.c
      word.w
      unicode.u
      
      *pointer
   EndStructureUnion
   string.s
EndStructure

Prototype DispatchProc(Array Param.multiDatatype(1))   ; <---------------
  
Structure t_dispatch
   *func.DispatchProc   ; <---------------
   Array Param.multiDatatype(10); max 10 parameter (one dimension)
EndStructure

Procedure DispatchMe(Array Param.multiDatatype(1)) ; one dimension expected
   Debug "x"    ; Breakpoint me and I'll crash [PB 4.50RC2 x86, Win7x64] -- Bug or programmers failure?
         ; Investigation Note: I crashes, because the Debugger want to dereference the Array...
EndProcedure
;---SNIP---
;...
;---SNIP---
; Allocate and Initialize dispatch structure
Define *temp.t_dispatch = AllocateMemory(SizeOf(t_dispatch))
InitializeStructure(*temp, t_dispatch)

*temp\func = @DispatchMe()
; But now if i comment those lines out it'll work
; But then the funcion only gets a Array with the size -1, not 10
; I thinks thats the error... But don't know why...
; If i would only use a .s Array, the error won't happen in the first place
; but after dereference the Array, the program also crash...
*temp\Param(0)\type = #PB_Long
*temp\Param(0)\long = 1000
;---SNIP---
;...
;---SNIP---

; So maybe the Problem is within here...
; Can't I push the Array as a CallFunctionFast Parameter?
*temp\func(*temp\Param())  ; <---------------
;---SNIP---
Benutzeravatar
Blackskyliner
Beiträge: 532
Registriert: 28.07.2005 00:54
Wohnort: /home/Blackskyliner/

Re: Array als Parameter, klappt nicht?

Beitrag von Blackskyliner »

Wird ein Dim Array eig. am ende der erstellenden Funktion gelöscht? Wenn ja, wie kann ich das dauerhaft erstellen... Denn wenn in meinem Fall, der ThreadProzess aufeinmal zu macht, würde dann ja aufgeräumt werden und in dem Fall, wenn erst danach der Dispatcher die Funktionen bearbeitet, das Array ungültig werden... Oder wie schaut das aus?

EDIT:
Habs grade gemerkt... wie kann ich nun am dümmsten ein Array dauerhaft initialisieren? Am besten sowas in der richtung von

Code: Alles auswählen

;Array mit 10 Integer werten Dim ArrayTemp(9) euqivalent
AllocateMemory(*ArrayTemp, SizeOf(Integer)*10)
oder wie geht das?


Edit2;
Danke freak du bist mein Held des Tages :allright: :allright: :allright:
Keine meiner Antworten ist endgültig, es kann passieren, dass ich den so eben geposteten Beitrag noch mehrmals ändere, um Doppelposts zu umgehen.
_________________
Purebasic Windows 7 x64 & Linux (Ubuntu 10.04LTS) 4.50[x64|x86] Nutzer
_________________
Projekte: YAED - Yet another Event Dispatcher
Antworten