Methode in C++ DLL mit Autoit aufrufen?

  • Hi,

    ich habe eine DLL (gpgFuncDll.dll) mit folgendem Inhalt:

    gpgFuncDLL.h

    Spoiler anzeigen

    gpgFuncDll.cpp

    Spoiler anzeigen


    Mir ist aber nun nicht klar wie ich mit DLLCall z.b. die Methode "Add" aufrufen kann.

    mfg

    Andy hat mir ein Schnitzel gebacken aber da war ein Raupi drauf und bevor Oscar das Bugfixen konnte kam Alina und gab mir ein AspirinJunkie.

    Einmal editiert, zuletzt von chip (3. Februar 2014 um 13:41)

  • Willst mir damit sagen, dass man mit Autoit nur Funktionen in Dlls aufrufen kann und kleine Klassen/Methoden?

    Andy hat mir ein Schnitzel gebacken aber da war ein Raupi drauf und bevor Oscar das Bugfixen konnte kam Alina und gab mir ein AspirinJunkie.

  • In der DLL müssen C-kompatible Schnittstellen definiert werden.
    Du musst also für deine zu exportierenden Methoden einen C-Wrapper schreiben.

    Beispiel:
    Du hast eine Klasse "MyClass" mit den Methoden "Add" und "Subtract":

    MyClass.h und MyClass.cpp

    MyClass.h:

    Code
    namespace myNameSpace
    {
    	class MyClass
    	{
    	public: 
    		double Add(double a, double b); 
    		double Subtract(double a, double b); 
    	};
    }


    MyClass.cpp:


    Um das ganze in C aufrufbar zu machen (und damit in AutoIt) musst du dir noch einen Wrapper schreiben:

    CWrapper.h und CWrapper.cpp

    CWrapper.h:

    Code
    extern "C" {
    	__declspec(dllexport) void* MyClass_new();
    	__declspec(dllexport) double MyClass_Add(void*, double, double);
    	__declspec(dllexport) double MyClass_Subtract(void*, double, double);
    }


    CWrapper.cpp:


    Jetzt muss das ganze noch in eine Dll kompiliert werden.
    Hier mal als Beispiel für den Visual C++ Compiler als x64-Dll (Pfade anpassen!):

    Dll kompilieren
    Code
    "C:\Program Files (x86)\Microsoft Visual Studio 11.0\VC\bin\amd64\cl.exe" /c MyClass.cpp
    
    
    "C:\Program Files (x86)\Microsoft Visual Studio 11.0\VC\bin\amd64\cl.exe" /c CWrapper.cpp
    
    
    "C:\Program Files (x86)\Microsoft Visual Studio 11.0\VC\bin\amd64\link.exe" /NXCOMPAT -dll /libpath:"C:\Program Files (x86)\Windows Kits\8.0\Lib\win8\um\x64" CWrapper.obj MyClass.obj


    Man sollte nun als Ergebnis eine CWrapper.dll bekommen haben welche man mit AutoIt folgendermaßen handhabt:

    erzeugte Dll in AutoIt nutzen
    [autoit]

    #AutoIt3Wrapper_UseX64=y

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

    Global Const $h_DLL = DllOpen("CWrapper.dll")

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

    ; Objekt erzeugen:
    Global $h_Object = DllCall($h_DLL, 'ptr:cdecl', 'MyClass_new')[0]

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

    ; Funktion MyClass.Add aufrufen:
    Global $f_Sum = DllCall($h_DLL, 'double:cdecl', 'MyClass_Add', "ptr", $h_Object, "double", 5.0, "double", 6.0)[0]
    ConsoleWrite(StringFormat("%20s:\t %f\n", "MyClass.Add", $f_Sum))

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

    ; Funktion MyClass.Subtract aufrufen:
    Global $f_Diff = DllCall($h_DLL, 'double:cdecl', 'MyClass_Subtract', "ptr", $h_Object, "double", 5.0, "double", 6.0)[0]
    ConsoleWrite(StringFormat("%20s:\t %f\n", "MyClass.Subtract", $f_Diff))

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

    DllClose($h_DLL)

    [/autoit]

    Edit: Werden bei euch auch keine Unterstriche im Code angezeigt? - beim Kopieren des Codes sind sie zwar da - sichtbar sind sie hier aber leider nicht.

    Einmal editiert, zuletzt von AspirinJunkie (3. Februar 2014 um 13:17)

  • Perfekt jetzt weiß ich bescheid. Danke AspirinJunkie.

    Andy hat mir ein Schnitzel gebacken aber da war ein Raupi drauf und bevor Oscar das Bugfixen konnte kam Alina und gab mir ein AspirinJunkie.

  • Wenn dir stdcall (man braucht dann kein :cdecl hinter den Rückgabetyp von DllCall zu schreiben) lieber ist dann müsste man den CWrapper und den AutoIt-Code folgendermaßen anpassen:

    CWrapper.h und CWrapper.cpp

    CWrapper.h:

    Code
    #define DLLOUT(Type) extern "C" __declspec(dllexport) Type __stdcall
    
    
    DLLOUT(void*)	MyClass_new();
    DLLOUT(double)	MyClass_Add(void*, double, double);
    DLLOUT(double)	MyClass_Subtract(void*, double, double);


    CWrapper.cpp:

    erzeugte Dll in AutoIt nutzen
    [autoit]

    #AutoIt3Wrapper_UseX64=y

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

    Global Const $h_DLL = DllOpen("CWrapper.dll")

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

    ; Objekt erzeugen:
    Global $h_Object = DllCall($h_DLL, 'ptr', 'MyClass_new')[0]

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

    ; Funktion MyClass.Add aufrufen:
    Global $f_Sum = DllCall($h_DLL, 'double', 'MyClass_Add', "ptr", $h_Object, "double", 5.0, "double", 6.0)[0]
    ConsoleWrite(StringFormat("%20s:\t %f\n", "MyClass.Add", $f_Sum))

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

    ; Funktion MyClass.Subtract aufrufen:
    Global $f_Diff = DllCall($h_DLL, 'double', 'MyClass_Subtract', "ptr", $h_Object, "double", 5.0, "double", 6.0)[0]
    ConsoleWrite(StringFormat("%20s:\t %f\n", "MyClass.Subtract", $f_Diff))

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

    DllClose($h_DLL)

    [/autoit]