Problem mit eigener DLL / DllCall()

  • Hallöle :)
    Da isser wieder, untreu wie immer und immer nur da wenn er Probleme hat.. :,(

    Ich möchte eine DLL erstellen und diese mit DllCall() aufrufen.

    Zum sinn:

    Ich spiele diverse spiele mit einem Gamepad / Joytokey. Nun kam ich auf diverse ideen, mit einem virtuellen Gamepad driver meine tastatur neu zu belegen.

    Das klappt ganz gut. :)

    PPJoy als Treiber, GlovePIE zum einstellen, evtl joytokey für diverse andere sachen.
    Aber leider ist GlovePIE ziemlich ziemlich eingeschränkt in gewissen funktionen.. Darum möchte ich au3 statt GlovePIE nutzen.
    Da ich nicht den hauch eines hinweises zum PPJoy (driver??) ansteuern gefunden hab, habe ich anhand eines anderem C scripts eine DLL gebastelt.
    Ich muss dazu sagen, das mir mehr oder minder 70% vom dlls erstellen nicht verstanden hab :) Bzw generell kein C beherrsche.. nur mal so grade 2-3 sachen gelesen ^^

    Der script den ich geändert hatte, war ein Beispielscript von PPJoy selber, um das ansteuern über C zu ermöglichen.
    Den habe ich umgeändert, eine while rausgenommen und die abfragen geändert, stattdessen eine simple parameter übergabe die die änderungen bestimmt, eingebaut.
    Das hatte ziemlich geharkelt, ich weiß bis jetzt nicht obs richtig ist^^" Aber Dev-Cpp gibt keinen fehler beim Compilen aus.

    So. ich habe eine DLL mit genau einer funktion, diese funktion scheint auch zu funktionieren.

    Aber wenn ich nun

    [autoit]

    HotKeySet("{Numpad0}", "test")
    while 1
    sleep(100)
    WEnd
    func test()
    DllCall($dll, "int", "ppjoy", "int", 1, "int", 1, "int", 1)
    EndFunc

    [/autoit]


    mache... nach dem DllCall ist ende. mein FakeDriver macht auch das was er soll, aber Autoit verursacht einen fehler und wird geschlossen.
    Eine Test-MsgBox unterhalb des DllCalls wird nichtmehr erreicht.

    Ich frage mich wo der fehler liegt..
    Mein Joytokey hat bei dem entsprechenden gamepad "a" als taste eingestellt. für die parameter gilt taste1,anschalten,joystick nummer.
    Wie gefordert wird "a" wiederholt gesendet sobald ich auf Numpad0 drücke. Doch autoit schmiert ab und sobald ich auf OK drücke hört das senden auf.

    Wo genau könnte der fehler liegen? Kann ich autoit zwingen fehler zu ignorieren und so evtl dem script am laufen zu halten? (debugweise bis ich die dll sauber hab!)
    Hier noch fix der DLL code, für wen der sich damit auskennt :]
    dllmain.c:

    Spoiler anzeigen


    /* Replace "dll.h" with the name of your header */
    #include "dll.h"
    #include <windows.h>
    #include <stdio.h>
    #include <stdlib.h>
    #include <stdio.h>
    #include <conio.h>
    #include <windows.h>

    #include <winioctl.h>

    #include "ppjioctl.h"

    #define NUM_ANALOG 8 /* Number of analog values which we will provide */
    #define NUM_DIGITAL 16 /* Number of digital values which we will provide */

    #pragma pack(push,1) /* All fields in structure must be byte aligned. */
    typedef struct
    {
    unsigned long Signature; /* Signature to identify packet to PPJoy IOCTL */
    char NumAnalog; /* Num of analog values we pass */
    long Analog[NUM_ANALOG]; /* Analog values */
    char NumDigital; /* Num of digital values we pass */
    char Digital[NUM_DIGITAL]; /* Digital values */
    } JOYSTICK_STATE;
    #pragma pack(pop)


    DLLIMPORT void HelloWorld ()
    {
    MessageBox (0, "Hello World from DLL!\n", "Hi", MB_ICONINFORMATION);
    }
    /* int ppjoysend (int argc, char **argv, int joy, int key)
    { */

    int ppjoy (int key, int state, int joy)
    {
    int argc;
    char **argv;

    HANDLE h;
    char ch;
    JOYSTICK_STATE JoyState;

    DWORD RetSize;
    DWORD rc;

    long *Analog;
    char *Digital;

    char *DevName;
    if (!joy)
    {
    DevName= "\\\\.\\PPJoyIOCTL1";
    }
    if (joy==1) /* ka obs klappt -> je nach index des joys diese devname ändern xD */
    {
    DevName= "\\\\.\\PPJoyIOCTL1";
    }
    if (joy==2)
    {
    DevName= "\\\\.\\PPJoyIOCTL2";
    }
    if (argc==2)
    {
    DevName= argv[1];
    }
    /* Open a handle to the control device for the first virtual joystick. */
    /* Virtual joystick devices are names PPJoyIOCTL1 to PPJoyIOCTL16. */
    h= CreateFile(DevName,GENERIC_WRITE,FILE_SHARE_WRITE,NULL,OPEN_EXISTING,0,NULL);

    /* Initialise the IOCTL data structure */
    JoyState.Signature= JOYSTICK_STATE_V1;
    JoyState.NumAnalog= NUM_ANALOG; /* Number of analog values */
    Analog= JoyState.Analog; /* Keep a pointer to the analog array for easy updating */
    JoyState.NumDigital= NUM_DIGITAL; /* Number of digital values */
    Digital= JoyState.Digital; /* Digital array */

    /* On each iteration clear position buffer: Analog in centre, buttons not pressed */
    Analog[0]= Analog[1]= Analog[2]= Analog[3]= Analog[4]= Analog[5]= Analog[6]= Analog[7]= (PPJOY_AXIS_MIN+PPJOY_AXIS_MAX)/2;
    memset (Digital,0,sizeof(JoyState.Digital));

    if (!state)
    {
    Digital[key]= 1; /* key = parameter 2. Steht für den Index der zahl die "angemacht" werden soll */
    }
    else
    {
    Digital[key]= state;
    }
    DeviceIoControl(h,IOCTL_PPORTJOY_SET_STATE,&JoyState,sizeof(JoyState),NULL,0,&RetSize,NULL);

    //MessageBox (0, "JO UNDSO from DLL!\n", "Hi", MB_ICONINFORMATION);
    //CloseHandle(h);
    //return 1;
    }

    BOOL APIENTRY DllMain (HINSTANCE hInst /* Library instance handle. */ ,
    DWORD reason /* Reason this function is being called. */ ,
    LPVOID reserved /* Not used. */ )
    {
    switch (reason)
    {
    case DLL_PROCESS_ATTACH:
    break;

    case DLL_PROCESS_DETACH:
    break;

    case DLL_THREAD_ATTACH:
    break;

    case DLL_THREAD_DETACH:
    break;
    }

    /* Returns TRUE on success, FALSE on failure */
    return TRUE;
    }


    dll.h :

    Spoiler anzeigen

    #ifndef _DLL_H_
    #define _DLL_H_

    #if BUILDING_DLL
    # define DLLIMPORT __declspec (dllexport)
    #else /* Not BUILDING_DLL */
    # define DLLIMPORT __declspec (dllimport)
    #endif /* Not BUILDING_DLL */

    DLLIMPORT void HelloWorld (void);

    DLLIMPORT int ppjoy (int key, int state, int joy);

    #endif /* _DLL_H_ */

    Die HelloWorld funktion war ein sample von Dev-Cpp ;) nicht beachten.

    Ich hoffe ich werde wegen der C-einlage hier nicht gesteinigt o.0

    Ich hoffe jmd versteht mein problem und meine formatierung ist nicht vollkommen ... verhunzt..
    ;)

    Einmal editiert, zuletzt von Phillipk (30. September 2008 um 17:12)

  • Servus Kollege ;) Ich versuche derzeit exakt das selbe, nur dass ich nicht meine Tastatur umbelegen möchte, sondern einfach nur DLLs für AutoIt coden und nutzen möchte.
    Zwei Tipps: 1. Dev-C++ ist veraltet. Nutze lieber eine freie IDE wie z.B. Code::Blocks (hab ich ;) ), 2. C an sich ist auch nicht mehr das neueste. Programmiere lieber in C++.
    Auf Link ist ein gutes Tutorial zu Cpp.
    Code schau ich mir morgen an :sleeping: (Außerdem: So gut bin ich aber auch noch net in C++).

    Projekte: Keine größeren (und fertigen)
    Gegen Internetzensur:
    https://epetitionen.bundestag.de/index.php?acti…s;petition=3860
    (Zeichnungsfrist abgelaufen)
    __________________________________________________________________________________________________________________________________
    Dieser Beitrag wurde bereits 264 mal editiert, zuletzt von »Fast2« (30. Februar 2009, 12:99)

  • Njoar, ich selbst kann nix weiter ausser teile von C/c++ codes verstehen.. Also, ein bisschen einlesen und nachvollziehen.
    Selbst was schreiben kann ich nicht wirklich.
    C / Dev-C++ habe ich nur genommen weils grade da war :)
    Mein "beispiel" code war in c, umformatieren wusste ich nicht wie ;)

    [autoit]


    DllCall($dll, "int:cdecl", "ppjoy", "int", 1, "int", 1, "int", 1)

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

    Daran hats gelegen o.0 Nun klappts o.o
    Warum genau klappts mit :cdect und ohne nicht? o.0 ich kann aus rein englisch-technischen gründen die erklärung nur halb verstehen -hust-.

  • Ohne überheblich zu klingen, aber ein bisschen quelltext kann ich doch schon verstehen ;o)

    Was ich vorhatte war eh die einfachste schublade o.o den hauptteil hatte ich schon, musste nurnoch aus einer abfrage eine parameter-nutzung basteln und das ganze als DLL compilen. Das war wohl das einzigste mal das ich eine dll erstellt hab, NIE WIEDER :D

    Ich habe ganz vergessen das hier auf [Erledigt] zu stellen (wenn das denn geht? x) ).. Die dll klappt super, alles was ich wollte funtzt.
    Ich bedanke mich recht herzlich bei allen postern das sie dennoch auf meine Stumpfe (und einfach zu lösende =.=*) frage geantwortet haben :)