wie yacas dll unter au3 nutzen?

  • Hallo Zusammen,

    meiner einer wäre sehr dankbar wenn hier ein "DLL Kündiger" antworten würde.

    Das Problem, ich möchte die yacasdll.dll unter Autoit3 nutzen, aber es funktioniert leider nicht so wie erhofft. Die Problemlösung ist evtl. auch für andere Leute interessant weil yacas ein kleines aber IMO mächtiges Computer Algebra System ist.
    (Allgemeine info zu yacas, und hier gibts es die DLL)

    Unter freepascal sieht eine lauffähige Lösung so aus:

    Normalerweise wäre es kein Problem das in Autoit um zu setzten, dachte ich :(

    Die yacas_init und yacas_result Funktion funktionieren auch in AU3, leider aber das wichtige yacas_eval nicht.
    Bach einiger Überlegung glaube ich, dass der Grund dafür ist, dass der C Ausdruck "YACASDLL_API void yacas_eval(char* expression)" keinen "str:cdecl" erwartet sondern einen Pointer auf einen char oder so etwas ähnliches. Ich steh nun wie der Ochs vorm Berg weil, 1. der freepascal compiler es scheinbar auch ohne pointer aufrufen kann, und ich mich mit den DllStructCreate und DllStructSetData gedönse in AU3, besonders wenn pointer im Spiel sind leider gar nicht auskenne.

    Vielen Dank. Mit freundlichen Grüßen
    uuchip

    Einmal editiert, zuletzt von uuchip (26. April 2012 um 10:27)

  • Nabend!
    Auf dem ersten Blick würde ich sagen, das du die Globale Variable VOR allen Funktionen Deklarieren mußt.

    Spoiler anzeigen
    [autoit]


    global $dllh
    func yacas_init()
    local $re
    $dllh = dllopen("yacasdll.dll")
    $re = dllcall($dllh,"none","yacas_init")
    ; writeln("init>"&@error)
    endfunc

    [/autoit] [autoit][/autoit] [autoit]

    func yacas_eval($s)
    local $re
    $ll = 100;try this
    $re = dllcall($dllh,"none","yacas_eval","str:cdecl",$s)
    ; writeln("eval>"&@error)
    endfunc

    [/autoit] [autoit][/autoit] [autoit]

    func yacas_result()
    local $re
    $re = dllcall($dllh,"str:cdecl","yacas_result")
    ; writeln("result>"&@error)
    return $re[0]
    endfunc

    [/autoit] [autoit][/autoit] [autoit]

    yacas_init()
    yacas_eval("1+1")
    writeln(yacas_result())
    dllclose($dllh)

    [/autoit]


    Versuche das mal, und gib anschliessend Resonaz ob es nur an der Deklarierung lag. Ausserdem würde ich das DllClose anders machen.

    Grüsse!

  • [quote='Techmix','index.php?page=Thread&postID=252758#post252758']Nabend!
    Auf dem ersten Blick würde ich sagen, das du die Globale Variable VOR allen Funktionen Deklarieren mußt.

    Moin Moin,

    danke für die Antwort, aber daran liegt es leider nicht, in AU3 kann "global" auch in einer Funktion stehen. Und grundsätzlich wird die yacasdll.dll ja auch aufgerufen nur die Datenübergabe an yacas_eval klappt leider nicht. Ich denke/ glaube das diese Funktion einen Pointer auf einen null terminierten string erwartet (pchar) aber ich bekomme es nicht auf die Reihe, z.B.

    Code
    $struct_Buffer = DllStructCreate("char[80]");
       DllStructSetData($struct_Buffer,1,$s)
       $re = dllcall($dllh,"none","yacas_eval","ptr:cdecl",DllStructGetPtr($struct_Buffer))

    funzt auch nicht. ?(

    Wenn das weiter so geht, werde ich autoit untreu und code wieder in freepascal ;)

    Gruß
    uuchip

    P.S.: Kann man eigentlich Funktionen einer dll über eine zweite dll aufgrufen? Wenn das funktionieren würde bastle ich mir eine Interface dll für yacas mit freepascal

  • Wenn das weiter so geht, werde ich autoit untreu und code wieder in freepascal

    Soweit muss es ja nicht kommen.

    Versuchs mal mit folgendem Aufbau:

    Yacas-DLL in AutoIt
    [autoit]

    #region
    #AutoIt3Wrapper_UseX64=n ; Wichtig wenn man eine 32Bit-DLL nutzen will !!!
    #endregion

    [/autoit] [autoit][/autoit] [autoit]

    Global $h_DLLYacas = -1

    [/autoit] [autoit][/autoit] [autoit][/autoit] [autoit]

    yacas_init()
    yacas_eval("Solve(x/(1+x) == a, x);")
    ConsoleWrite(yacas_result() & @CRLF)
    yacas_exit()

    [/autoit] [autoit][/autoit] [autoit][/autoit] [autoit][/autoit] [autoit][/autoit] [autoit][/autoit] [autoit]

    Func yacas_init()
    Dim $h_DLLYacas = DllOpen("yacasdll.dll")
    If @error Then Return SetError(1, @error, False)
    DllCall($h_DLLYacas, "none:cdecl", "yacas_init")
    If @error Then Return SetError(2, @error, False)
    Return True
    EndFunc ;==>yacas_init

    [/autoit] [autoit][/autoit] [autoit]

    Func yacas_eval(Const $s_String)
    If $h_DLLYacas = -1 Then Return SetError(1, 0, False)
    DllCall($h_DLLYacas, "none:cdecl", "yacas_eval", "str", $s_String)
    If @error Then Return SetError(2, @error, False)
    Return True
    EndFunc ;==>yacas_eval

    [/autoit] [autoit][/autoit] [autoit]

    Func yacas_result()
    If $h_DLLYacas = -1 Then Return SetError(1, 0, False)
    Local $a_Ret = DllCall($h_DLLYacas, "str:cdecl", "yacas_result")
    If @error Then Return SetError(2, @error, "")
    Return $a_Ret[0]
    EndFunc ;==>yacas_result

    [/autoit] [autoit][/autoit] [autoit]

    Func yacas_exit()
    If $h_DLLYacas = -1 Then Return SetError(1, 0, False)
    DllCall($h_DLLYacas, "none:cdecl", "yacas_exit")
    DllClose($h_DLLYacas)
    EndFunc ;==>yacas_result

    [/autoit]

    Einmal editiert, zuletzt von AspirinJunkie (26. April 2012 um 09:00)

  • So sollte es stimmen:

    [autoit]

    $formula = "1 + 1"

    [/autoit][autoit][/autoit][autoit]

    global $dllh = dllopen("yacasdll.dll")

    [/autoit][autoit][/autoit][autoit]

    dllcall($dllh,"none:cdecl","yacas_init")

    [/autoit][autoit][/autoit][autoit]

    ConsoleWrite("<: " & $formula & @LF)
    dllcall($dllh,"none:cdecl","yacas_eval","str",$formula)

    [/autoit][autoit][/autoit][autoit]

    $re = dllcall($dllh,"str:cdecl","yacas_result")
    ConsoleWrite("> " & $re[0] & @LF)

    [/autoit][autoit][/autoit][autoit]

    dllcall($dllh,"none:cdecl","yacas_exit")

    [/autoit]


    Edit: AspirinJunkie war schneller mit der ganzen UDF

  • Hallo AspirinJunkie & progandy und die anderen,

    herzlichen Dank für die Lösung! :):):)
    Und weil man hier so "gut geholfen bekommt", werde ich autoit natürlich nicht untreu!

    Megens Grüße
    uuchip

    P.S.: Wie gesagt die Lösung hat evtl. auch Bedeutung für andere Programmierer die sich mit Mathe beschäftigen. yacas ist zwar kein maxima oder maple aber doch verdammt leistungsfähig, ich würde mal behaupten es kann mehr als man in der Oberstufe Matheleistung so braucht

    P.P.S.: Ich brauch's für http://projecteuler.net/, dieser link sei jedem empfohlen der gerne programmiert und knobelt.