DllCall funktioniert nicht

  • Hallo,
    ich versuche erfolglos einen DLLcall auszuführen. Die ersten beiden calls funktionieren, der dritte call weigert sich beharrlich was sinnvolles, also die Seriennummer zurückzugeben. Das Array $snIOW bleibt schlicht leer.

    Der entsprechende Aufruf aus "C" heraus funktioniert:

    PVOID devHandle;
    int numIows;
    WCHAR sn[9];

    // Open device
    devHandle = IowKitOpenDevice();
    // Get number of IOWs in system
    numIows = IowKitGetNumDevs();
    // Get device handle and init object
    devHandle = IowKitGetDeviceHandle();
    // Get serial number
    IowKitGetSerialNumber(devHandle, sn);

    Kann mir jemand sagen was ich falsch mache?

    Gruß
    Freitag

    Einmal editiert, zuletzt von Freitag (9. März 2009 um 18:37)

    • Offizieller Beitrag

    Hi,

    du hast doch schon am Anfang Probleme oder?

    [autoit]

    Global $dllIOW, $rslt1IOW, $rslt2IOW, $ptrIOW[16], $snIOW[9], $rslt1IOW

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

    ;Dll öffnen
    $dllIOW = DllOpen("iowkit.dll")
    ;IOWhandle übergeben
    $ptrIOW = DllCall($dllIOW, "ptr", "IowKitOpenDevice")
    If Not IsArray($ptrIOW) Then ConsoleWrite("Mist" & @CRLF)
    ;Anzahl der angeschlossenen Bausteine abfragen
    $rslt1IOW = DllCall($dllIOW, "int", "IowKitGetNumDevs")
    If Not IsArray($rslt1IOW) Then ConsoleWrite("Mist1" & @CRLF)
    ;ProductID abfragen
    $rslt2IOW = DllCall($dllIOW, "dword", "IowKitGetProductId", "ptr", $ptrIOW[0])
    If Not IsArray($rslt2IOW) Then ConsoleWrite("Mist2" & @CRLF)
    ;Seriennummer auslesen
    DllCall($dllIOW, "char", "IowKitGetSerialNumber", "ptr", $ptrIOW[0], "wchar", $snIOW)

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

    ;IOWhandle freigeben
    DllCall($dllIOW, "int", "IowKitCloseDevice", "ptr", $ptrIOW)
    ;Dll schließen
    DllClose($dllIOW)

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

    ;Anzeige
    ConsoleWrite("NUM " & $rslt1IOW[0] & @CRLF)
    ConsoleWrite("PID " & "0x" & Hex($rslt2IOW[0]) & @CRLF)
    ConsoleWrite("S/N " & $snIOW & @CRLF)

    [/autoit]

    Mega

  • Mahlzeit,
    leider nicht. Die Konsole spuckt folgendes aus:

    NUM 1
    PID 0x00001500
    S/N

    Mist wär ja ein Ansatz aber NUM und PID stimmen und bei S/N sollte 377E stehen.

    Gruß
    Freitag

  • Danke erstmal. Ja klar, die DLL wär nicht das Problem aber ohne den zugehörigen Baustein gings dann trotzdem nicht.
    Also ich probier jetzt schon ein paar Tage an dem Aufruf rum und hab vieles ausprobiert was nur noch der Taskmanager beheben konnte :rolleyes: .
    Was mir noch nicht ganz klar bei der Sache ist, ist folgendes:

    Die ersten beiden Calls führen zu einem Rückgabewert der Funktion nach dem Motto
    $ergebnis = DllCall(...
    was funktioniert
    Beim dritten Aufruf bekommt die Funktion einen zusätzlichen Parameter übergeben und soll diesen verändern, was nicht funktioniert. Laut AutoIt-Hilfe sollte der Funktionsaufruf, eigentlich die Kopie des Ergebnisses des Rückgabewertes des Funktionsaufrufs liefern (mein Sorry zum Deutsch). Alle meine Versuche in diese Richtung sind bisher kläglich gescheitert.

    Hat dazu vielleicht jemand ne Idee?

    Freitag

  • noch ein Nachtrag:

    Code
    $rslt3IOW = DllCall($dllIOW, "char", "IowKitGetSerialNumber", "ptr", $ptrIOW[0], "wchar", $snIOW)
    
    
    GUICtrlSetData($edt3IOW, "S/N " & $rslt3IOW)


    liefert zumindest mal eine Null als Ergebnis. Da denk ich mir, könnte ja eine der führenden Nullen sein aus 00000377E.

    Code
    GUICtrlSetData($edt3IOW, "S/N " & $rslt3IOW[8])


    wird dann aber mit nem Absturz quittiert:

    ==> Subscript used with non-Array variable.:
    GUICtrlSetData($edt3IOW, "S/N " & $rslt3IOW[8])
    GUICtrlSetData($edt3IOW, "S/N " & $rslt3IOW^ ERROR

    Deshalb Konfusion meinerseits ;( und mein Hilferuf. Mir fehlt der Ansatz!

  • ACHTUNG: Beim DLLCall ist statt dem Typ PWCHAR (Pointer zu einem WChar-Buffer) WSTR zu verwenden ;) Und der gefüllte String dann aus dem Rückgabearray auslesen:

    [autoit]

    $rslt3IOW = DllCall($dllIOW, "char", "IowKitGetSerialNumber", "ptr", $ptrIOW[0], "wstr", "")
    $snIOW = $rslt3IOW[2]

    [/autoit]


    Du könntst natürlich auch einen Buffer selbst anlegen: (Hier heißt es dann wchar)

    [autoit]

    $buffer = DLLStructCreate("wchar[9]")
    $rslt3IOW = DllCall($dllIOW, "char", "IowKitGetSerialNumber", "ptr", $ptrIOW[0], "ptr", DLLStructGetPtr($buffer))
    $snIOW = DllstructGetData($buffer, 1)

    [/autoit]


    //Edit: @All: API ist hier: http://www.codemercs.com/uploads/tx_sbd…_V15_API_01.pdf

  • Hab's ausprobiert und funktioniert :thumbup: , die Welt kann so einfach sein ...keine Nachtschicht, Yeah!

    Meine Hochachtung und vielen, vielen Dank

    Freitag