Bug mit CallFunctionFast() oder Fehler von mir?

Hier kann alles mögliche diskutiert werden. Themen zu Purebasic sind hier erwünscht.
Flames und Spam kommen ungefragt in den Mülleimer.
Benutzeravatar
NicTheQuick
Ein Admin
Beiträge: 8809
Registriert: 29.08.2004 20:20
Computerausstattung: Ryzen 7 5800X, 64 GB DDR4-3200
Ubuntu 24.04.2 LTS
GeForce RTX 3080 Ti
Wohnort: Saarbrücken

Bug mit CallFunctionFast() oder Fehler von mir?

Beitrag von NicTheQuick »

Folgender Code:

Code: Alles auswählen

Procedure.f Function(x.f)
  ProcedureReturn (((x - 2) * x + 3) * x - 1)
EndProcedure

Procedure.f Diff(*Function, x.f, eps.f)
  Protected h.f, m.f, y.f, m_old.f
  
  h = 1
  Repeat
    m_old = m
    
    ;folgende Zeile sollte das selbe machen
    ;m = (CallFunctionFast(*Function, x + h) - CallFunctionFast(*Function, x - h)) / (2 * h)
    
    ;wie diese:
    m = (Function(x + h) - Function(x - h)) / (2 * h)
    
    h * 0.5
  Until Abs(m_old - m) < eps
  
  ProcedureReturn m
EndProcedure

s.s = ""
For a.l = -10 To 10
  s + StrF(Diff(@Function(), a / 10, 0.001)) + #CRLF$
Next
MessageRequester("Ableitung", s)
Ich glaube [c]CallFunctionFast()[/c] kommt mit Float-Rückgabewerten nicht
richtig zurecht.
Benutzeravatar
HeX0R
Beiträge: 3042
Registriert: 10.09.2004 09:59
Computerausstattung: AMD Ryzen 7 5800X
96Gig Ram
NVIDIA GEFORCE RTX 3060TI/8Gig
Win11 64Bit
G19 Tastatur
2x 24" + 1x27" Monitore
Glorious O Wireless Maus
PB 3.x-PB 6.x
Oculus Quest 2 + 3
Kontaktdaten:

Beitrag von HeX0R »

Jau, das geht nicht so ohne weiteres, siehe hier .

Dein Beispiel wäre also:

Code: Alles auswählen

Structure DWORD
  StructureUnion
   l.l
   f.f
  EndStructureUnion
EndStructure

Procedure.l Function(x.f)
  result.DWORD\f = (((x - 2) * x + 3) * x - 1)
  ProcedureReturn result\l
EndProcedure

Procedure.f Diff(*Function, x.f, eps.f)
  Protected h.f, m.f, y.f, m_old.f
 
  h = 1
  Repeat
    m_old = m
   
    ;folgende Zeile sollte das selbe machen
    i.DWORD\l = CallFunctionFast(*Function, x + h)
    j.DWORD\l = CallFunctionFast(*Function, x - h) 
    m = (i\f - j\f) / (2 * h)
   
    ;wie diese:
    ;m = (Function(x + h) - Function(x - h)) / (2 * h)
   
    h * 0.5
  Until Abs(m_old - m) < eps
 
  ProcedureReturn m
EndProcedure

s.s = ""
For a.l = -10 To 10
  s + StrF(Diff(@Function(), a / 10, 0.001)) + #CRLF$
Next
MessageRequester("Ableitung", s)
Benutzeravatar
NicTheQuick
Ein Admin
Beiträge: 8809
Registriert: 29.08.2004 20:20
Computerausstattung: Ryzen 7 5800X, 64 GB DDR4-3200
Ubuntu 24.04.2 LTS
GeForce RTX 3080 Ti
Wohnort: Saarbrücken

Beitrag von NicTheQuick »

Blöde Sache. :roll:

Aber Danke für die Hilfe! :allright:
Benutzeravatar
ts-soft
Beiträge: 22292
Registriert: 08.09.2004 00:57
Computerausstattung: Mainboard: MSI 970A-G43
CPU: AMD FX-6300 Six-Core Processor
GraKa: GeForce GTX 750 Ti, 2 GB
Memory: 16 GB DDR3-1600 - Dual Channel
Wohnort: Berlin

Beitrag von ts-soft »

Das Problem hierbei ist, das PB bei Prozeduren immer Long zurück gibt.
Lediglich der Stringpointer wird automatisch umgewandelt. Bei Float ist also entweder PeekF oder diese Strukture erforderlich.
Deshalb ist z.B. Procedure.b auch überflüssig, es kommt trotzdem ein Long :wink:
PureBasic 5.73 LTS | SpiderBasic 2.30 | Windows 10 Pro (x64) | Linux Mint 20.1 (x64)
Nutella hat nur sehr wenig Vitamine. Deswegen muss man davon relativ viel essen.
Bild
Benutzeravatar
NicTheQuick
Ein Admin
Beiträge: 8809
Registriert: 29.08.2004 20:20
Computerausstattung: Ryzen 7 5800X, 64 GB DDR4-3200
Ubuntu 24.04.2 LTS
GeForce RTX 3080 Ti
Wohnort: Saarbrücken

Beitrag von NicTheQuick »

Ja, habe ich mir im Nachhinein auch gedacht. Aber das ist ja auch nur bei
[c]CallFunctionFast()[/c] so, oder? Wenn man dieser Funktion einen
Pointer zu einer Funktion übergibt, kann die ja nicht wissen, was
zurückgegeben werden soll.
Benutzeravatar
ts-soft
Beiträge: 22292
Registriert: 08.09.2004 00:57
Computerausstattung: Mainboard: MSI 970A-G43
CPU: AMD FX-6300 Six-Core Processor
GraKa: GeForce GTX 750 Ti, 2 GB
Memory: 16 GB DDR3-1600 - Dual Channel
Wohnort: Berlin

Beitrag von ts-soft »

Procedure.b gibt auch ein Long zurück, funzt also nur, wenn du als Ergebnis
eine Byte-Variable verwendest.
Aber das soll ja alles besser werden :wink:

Code: Alles auswählen

Procedure.b Test()
  ProcedureReturn 1000
EndProcedure

Debug Test()
Dürfte ja nicht funzen :mrgreen:
PureBasic 5.73 LTS | SpiderBasic 2.30 | Windows 10 Pro (x64) | Linux Mint 20.1 (x64)
Nutella hat nur sehr wenig Vitamine. Deswegen muss man davon relativ viel essen.
Bild
Benutzeravatar
MVXA
Beiträge: 3823
Registriert: 11.09.2004 00:45
Wohnort: Bremen, Deutschland
Kontaktdaten:

Beitrag von MVXA »

Habe jetzt nicht komplett alles gelesen aber das könnte vielleicht
funktionieren:

Float Rückgaben werden immer auf dem FloatStack geschrieben. Das
müsste auch bei der DLL so sein. Du müsstest jetzt die CallFunctionFast
in eine eigene Procedur kapseln, die so aussieht:

Code: Alles auswählen

procedure.f GetFloatDLL(*pProc.l, lParamA.l, lParamB.l)
    CallFunctionFast(*pProc, lParamA, lParamB)
    ProcedureReturn
endprocedure
Natürlich sollte der Bug gefixt werden aber das ist bis jetzt meiner Meinung
nach aber die beste Lösung das zu umgehen.
Bild
Antworten