Seite 1 von 1

Bug mit CallFunctionFast() oder Fehler von mir?

Verfasst: 12.01.2006 23:59
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.

Verfasst: 13.01.2006 00:31
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)

Verfasst: 13.01.2006 07:33
von NicTheQuick
Blöde Sache. :roll:

Aber Danke für die Hilfe! :allright:

Verfasst: 13.01.2006 09:17
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:

Verfasst: 13.01.2006 14:12
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.

Verfasst: 13.01.2006 14:37
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:

Verfasst: 13.01.2006 15:36
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.