Eigene DLL mit Autoit ansprechen - Pointer ?

  • Halli - Hallo,

    In einem derzeitigen Projekt möchte ich die Position des Mondes am Himmel
    numerisch iterativ berechnen. Die Reihen dafür stehen so gut wie, und ich wollte mir schonmal überlegen,
    wie das programmiertechnisch umsetzbar ist. ;)
    Fakt ist: Extrem viele Rechnungen.
    Fakt ist: AutoIt ist.. langsam.. seeehr langsam ;)

    Daher dachte ich mir - lager die Rechnungen doch aus, in eine DLL, geschrieben in C.
    Nun sind meine Kenntnisse in C extrem gering - unterhalb der Oberfläche.. :p

    Da die Funktion sehr viele Parameter braucht und sehr viele Werte zurückgeben soll, habe ich vor, das mit Arrays zu erledigen.
    Meine Überlegung war:
    Ich übergebe der Funktion in der Dll zwei Pointer:
    Einen zu einer Double[n]-struct mit den Startparametern,
    einen zu einer leeren Double[m]-struct, in die die Funktion die Endwerte eintragen soll.
    Leichter gesagt als getan.

    Bisher sieht mein Script folgendermaßen aus:

    Spoiler anzeigen
    [autoit]

    #include <Array.au3>

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

    $dll = DllOpen( 'testdll.dll' )

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

    $struct = DllStructCreate( 'double[3];double[3]' )
    DllStructSetData( $struct, 1, 123, 1 )
    DllStructSetData( $struct, 1, 456, 2 )
    DllStructSetData( $struct, 1, 789, 3 )

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

    MsgBox( 0, 'data', DllStructGetData( $struct, 1, 1 ) & @CRLF & _
    DllStructGetData( $struct, 1, 2 ) & @CRLF & _
    DllStructGetData( $struct, 1, 3) )

    $r = DllCall( $dll, 'double:cdecl', 'moonpos', 'double*', DllStructGetPtr( $struct, 1 ), 'double', 5, 'double*', DllStructGetPtr( $struct, 2 ) )
    MsgBox( 0, '', @error )

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

    _ArrayDisplay( $r )
    MsgBox( 0, '', DllStructGetData( $struct, 2, 1 ) )

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

    DllClose( $dll )

    [/autoit]
    Spoiler anzeigen


    Allerdings liefert mir $r [ 0, 0, 5, 0],
    d.h. Mpos0x - also die Startwerte - sind in der Funktion nicht angekommen,
    und mit den Pointern passt auch etwas nicht. Wobei ein separater Test mit
    DllStructGetPtr doch Speicheradressen ausgibt.

    Und ich habe leider keine Ahnung, wie dieser Fehler zu beheben ist... :rolleyes:

    Gruß, limette

    There are only 10 types of people in the world:
    Those who understand binary - and those who don't.

    Einmal editiert, zuletzt von limette (22. Oktober 2009 um 21:07)

    • Offizieller Beitrag


    Du gibst ja tatsächlich nur die Startwerte zurück.

    Übrigens ist mir nicht klar, was du überhaupt berechnen willst. :S

  • Hi,

    probiere es einmal so...

    [autoit]

    $r = DllCall( $dll, 'double:cdecl', 'moonpos', 'ptr', DllStructGetPtr( $struct, 1 ), 'double', 5, 'ptr', DllStructGetPtr( $struct, 2 ) )
    MsgBox( 0, '', @error )

    [/autoit]

    Bist Du sicher, dass deine C-Funktion korrekt ist (debugged)?

    BugFix
    Mpos0x, Mpos0y, Mpos0z wird in 'ret' abgelegt.


    Gruß
    Greenhorn


  • BugFix :
    Das war mir durchaus bewusst ;)
    Dass im Return wieder ein Startwert steht ist nur ein Test, ob denn wenigstens die Werte in der Funktion ankommen und
    nur das Schreiben der Antwort fehlschlägt,
    oder der eben nichtmal die Startwerte bekommt.
    Die ganzen Berechnungen folgen später, es geht mir gerade nur um das Übermitteln von Informationen ;)

    Greenhorn:
    ...
    ...
    Du bist mein Fräund :D
    Es funktioniert, die Inhalte der Array sind vernünftig, der Return - also $r[0] stimmt und das Auslesen aus
    dem 2. Struct mit
    DllStructGetData( $struct, 2, 1 )
    läuft auch !
    Dankedankedankedanke =)

    Edit:
    Ach, und ich war mir nicht sicher, ob die C-Funktion korrekt ist ;)
    Dev-C++ hat keinen Fehler gemeldet..
    Aber wozu gibt es bei der DllCall-Funktion in AutoIt dann die Angabe "double*" etc, also mit "*" für Pointer ?

    There are only 10 types of people in the world:
    Those who understand binary - and those who don't.

  • Ach, und ich war mir nicht sicher, ob die C-Funktion korrekt ist ;)
    Dev-C++ hat keinen Fehler gemeldet..
    Aber wozu gibt es bei der DllCall-Funktion in AutoIt dann die Angabe "double*" etc, also mit "*" für Pointer ?


    Dev-C++ wird nicht mehr weiterentwickelt (seit Jahren nicht mehr) und enthält diverse Bugs.
    Viel besser ist Code::Blocks. Entweder mit MinGW oder einem Compiler aus der Liste ...
    Oder Pelles C, ist auch gut.


    Gruß
    Greenhorn