Seite 1 von 1
Array als Parameter, klappt nicht?
Verfasst: 08.06.2010 11:05
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
Re: Array als Parameter, klappt nicht?
Verfasst: 08.06.2010 11:11
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!
Re: Array als Parameter, klappt nicht?
Verfasst: 08.06.2010 11:16
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---
Re: Array als Parameter, klappt nicht?
Verfasst: 08.06.2010 12:18
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.
Re: Array als Parameter, klappt nicht?
Verfasst: 08.06.2010 14:13
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...
Re: Array als Parameter, klappt nicht?
Verfasst: 08.06.2010 14:34
von STARGÅTE
wieso der saubere weg geht ja auch, nur halt nicht mit CallFunctionFast !
Sonden nur normal, mit Procedure und Prototype
Re: Array als Parameter, klappt nicht?
Verfasst: 08.06.2010 14:47
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!
Re: Array als Parameter, klappt nicht?
Verfasst: 08.06.2010 15:10
von STARGÅTE
jo stimmt, dann ist das wohl veraltet.
aber das mit Felderanzahl sollte stimmen.
Re: Array als Parameter, klappt nicht?
Verfasst: 08.06.2010 16:05
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---
Re: Array als Parameter, klappt nicht?
Verfasst: 08.06.2010 16:14
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
