dll in Projekt einbinden "gelöst"



  • Ein hi an jeden!

    Ich habe vor einiger Zeit begonnen ein USB-Projekt zu beginnen. Eines was ich auf
    http://www.sprut.de/electronic/pic/8bit/18f/programm/usb2550/usb2550.htm
    gefunden habe. Die Software für den Microcontroller habe ich fertig und diese funktioniert, das konnte ich mit dem mitgelieferten Testprogramm der HP und mittels Windowskompatiblitätsmodus prüfen.

    Mein Ziel ist nun eine eigene Win-Konsole zu programmieren um auf den Chip zuzugreifen. Das funktioniert soweit auch. Die Anwendung lässt sich starten, das Dll-File wird angeblich auch geladen, jedoch stürzt die Anwendung ab, sobald sie eine Funktion der Dll-File benutzen möchte. Es wäre super wenn sich hier ein Profi finden würde, der mir bei meinem Problem etwas Support geben könnte 🙄

    Jede andere Hilfe Tutorials oder sonstiges sind auch gerne gesehen 🙂

    Informationen zum Projekt selbst:

    -DLL Datei: mpusbapi.dll
    //von Microchip
    //http://ww1.microchip.com/downloads/en/DeviceDoc/MCHPFSUSB_Setup_v1.3.exe
    //Eine Headerfile in C++ ist gegeben
    -C++ Kompiler: Dev Cpp
    Betriebssystem: Windows7 Home wohl 64Bit
    Anwenderkenntnisse in C++: mäßig

    Bisherige Vorgehensweise: Ich habe die Dateien von Microchip gedownloaded und das µC-Programm geschrieben/die Dateien von Sprut richtig eingefügt und nachvollzogen.

    Für die Win-Konsole habe ich Dateien aus dem Ordner Festplatte:MCHPFSUSB\Pc\Mpusbapi\Dll die gegebene C++-File und Header-File in mein Projekt übernommen und gerngfügig Geändert. Ist mein Vorgehen denn so korrekt oder mache ich es mir damit einfach zu leicht?

    mpusbapi.c

    /*********************************************************************
     *
     *                Example 01 - Load-time Linking
     *
     *********************************************************************
     * FileName:        mpusbapi.cpp
     * Dependencies:    None
     * Compiler:        DevC++ 4.9.9.2
     * Company:         Copyright (C) 2011 P_Engineering
     *
     * Software License Agreement
     *
     * none;)
     *
     * THIS SOFTWARE IS PROVIDED IN AN “AS IS” CONDITION. NO WARRANTIES,
     * WHETHER EXPRESS, IMPLIED OR STATUTORY, INCLUDING, BUT NOT LIMITED
     * TO, IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
     * PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. THE COMPANY SHALL NOT,
     * IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL OR
     * CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER.
     *
     * Author               Date        Comment
     *~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
     *   -                10.08.11
     ********************************************************************/
    
    //---------------------------------------------------------------------------
    
    #include <stdio.h>
    #include <windows.h>
    #include <string.h>
    #include <setupapi.h>
    #include <initguid.h>
    #include <winioctl.h>
    #include "mpusbapi.h"                  // MPUSBAPI Header File
    #include <cstdlib>
    #include <iostream>
    
    //---------------------------------------------------------------------------
    //#pragma argsused
    
    // Global Vars
    char vid_pid[]= "vid_04d8&pid_000c";    // Default Demo Application Firmware
    char out_pipe[]= "\\MCHP_EP1";
    char in_pipe[]= "\\MCHP_EP1";
    
    DWORD temp;
    
    HANDLE myOutPipe;
    HANDLE myInPipe;
    HANDLE myRueckgabewert;
    HMODULE MPUSBAPI;
    
    //---------------------------------------------------------------------------
    // Prototypes
    void GetSummary(void);
    
    //---------------------------------------------------------------------------
    
    int main(int argc, char* argv[])
    {
        BOOLEAN bQuit;
        DWORD selection;
        bQuit = false;
    
    MPUSBAPI=LoadLibrary("mpusbapi.dll");
    
        if (!MPUSBAPI) 
           printf("dll nicht geladen\r\n");
        else
            printf("dll geladen\r\n");
    
    /*Ist der Folgeteil nicht aus Kommentiert
    //typedef DWORD (*MPUSBGetDLLVersion)(void);
    //MPUSBGetDLLVersion MPUSBGetDLLVersionHolder;
    //
    //folgt die Fehlermeldung vom Compiler:
    //107 D:\Programme\Dev-Cpp\Source\C\mpusbapi.c 
    //invalid conversion from `DWORD (*)()' to `DWORD' 
    */
        // Always a good idea to initialize the handles
        myOutPipe = myInPipe = INVALID_HANDLE_VALUE;
    
        printf("Microchip Technology Inc., 2004\r\n");
        printf("===============================\r\n");
        while(!bQuit)
        {
            printf("Select an option\r\n");
            printf("[1] Get MPUSBAPI Version\r\n");
            printf("[2] Summarize Instances\r\n");
            printf("[3] -\r\n");
            printf("[4] Quit\r\n>>");
            scanf("%d",&selection);
    
            switch(selection)
            {
                case 1:
                    temp = MPUSBGetDLLVersion();
                    printf("MPUSBAPI Version: %d.%d\r\n",HIWORD(temp),LOWORD(temp));
                    break;
                case 2:
                    GetSummary();
                    break;
                case 3:
                    // Place Holder
                    break;
                case 4:
                    bQuit = true;
                    break;
                default:
                    break;
            }// end switch
    
            fflush(stdin);printf("\r\n");
        }//end while
    
        // Always check to close all handles before exiting!
        if (myOutPipe != INVALID_HANDLE_VALUE) MPUSBClose(myOutPipe);
        if (myInPipe != INVALID_HANDLE_VALUE) MPUSBClose(myInPipe);
        myOutPipe = myInPipe = INVALID_HANDLE_VALUE;
    
        return 0;
    }//end main
    
    //---------------------------------------------------------------------------
    
    void GetSummary(void)
    {
        HANDLE tempPipe = INVALID_HANDLE_VALUE;
        DWORD count = 0;
        DWORD max_count;
    
        max_count = MPUSBGetDeviceCount(vid_pid);
    
        printf("\r\n%d device(s) with %s currently attached\r\n",max_count,vid_pid);
    
        // Note:
        // The total number of devices using the generic driver could be
        // bigger than max_count. They could have different vid & pid numbers.
        // This means if max_count is 2, the valid instance index do not
        // necessary have to be '0' and '1'.
        //
        // Below is a sample code for searching for all valid instance indexes.
        // MAX_NUM_MPUSB_DEV is defined in _mpusbapi.h
    
        count = 0;
        for(int i = 0; i < MAX_NUM_MPUSB_DEV; i++)
        {
            tempPipe = MPUSBOpen(i,vid_pid,NULL,MP_READ,0);
            if(tempPipe != INVALID_HANDLE_VALUE)
            {
                printf("Instance Index # %d\r\n",i);
                MPUSBClose(tempPipe);
                count++;
            }
            if(count == max_count) break;
        }//end for
        printf("\r\n");
    }//end GetSummary
    
    //---------------------------------------------------------------------------
    

    die dazu gehörige Header-Datei, an der ich nicht gefuscht Habe;):

    /*********************************************************************
     *
     *                  MPUSBAPI Library Version 1.00
     *
     *********************************************************************
     * FileName:        mpusbapi.h
     * Dependencies:    None
     * Compiler:        C++
     * Company:         Copyright (C) 2004 by Microchip Technology, Inc.
     *
     * Software License Agreement
     *
     * The software supplied herewith by Microchip Technology Incorporated
     * (the “Company”) for its PICmicro® Microcontroller is intended and
     * supplied to you, the Company’s customer, for use solely and
     * exclusively on Microchip PICmicro Microcontroller products. The
     * software is owned by the Company and/or its supplier, and is
     * protected under applicable copyright laws. All rights are reserved.
     * Any use in violation of the foregoing restrictions may subject the
     * user to criminal sanctions under applicable laws, as well as to
     * civil liability for the breach of the terms and conditions of this
     * license.
     *
     * THIS SOFTWARE IS PROVIDED IN AN “AS IS” CONDITION. NO WARRANTIES,
     * WHETHER EXPRESS, IMPLIED OR STATUTORY, INCLUDING, BUT NOT LIMITED
     * TO, IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
     * PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. THE COMPANY SHALL NOT,
     * IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL OR
     * CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER.
     *
     * Author               Date        Comment
     *~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
     * Ross Fosler          9/2/04      Implemented MPUSBGetDeviceLink()
     * Rawin Rojvanit       11/19/04    Original version 1.00 completed
     ********************************************************************/
    
    #ifndef _MPUSBAPI_H_
    #define _MPUSBAPI_H_
    
    #define	MPUSB_FAIL                  0
    #define MPUSB_SUCCESS               1
    
    #define MP_WRITE                    0
    #define MP_READ                     1
    
    // MAX_NUM_MPUSB_DEV is an abstract limitation.
    // It is very unlikely that a computer system will have more
    // then 127 USB devices attached to it. (single or multiple USB hosts)
    #define MAX_NUM_MPUSB_DEV           127
    
    DWORD (*MPUSBGetDLLVersion)(void);
    
    DWORD (*MPUSBGetDeviceCount)(PCHAR pVID_PID);
    
    HANDLE (*MPUSBOpen)(DWORD instance,         // Input
                     PCHAR pVID_PID,            // Input
                     PCHAR pEP,                 // Input
                     DWORD dwDir,               // Input
                     DWORD dwReserved);         // Input <Future Use>
    
    DWORD (*MPUSBRead)(HANDLE handle,           // Input
                    PVOID pData,                // Output
                    DWORD dwLen,                // Input
                    PDWORD pLength,             // Output
                    DWORD dwMilliseconds);      // Input
    
    DWORD (*MPUSBWrite)(HANDLE handle,          // Input
                     PVOID pData,               // Input
                     DWORD dwLen,               // Input
                     PDWORD pLength,            // Output
                     DWORD dwMilliseconds);     // Input
    
    DWORD (*MPUSBReadInt)(HANDLE handle,        // Input
                       PVOID pData,             // Output
                       DWORD dwLen,             // Input
                       PDWORD pLength,          // Output
                       DWORD dwMilliseconds);   // Input
    
    BOOL (*MPUSBClose)(HANDLE handle);
    
    #endif
    


  • So wie es aussieht fehlt GetProcAdress für alle Funktionen in der DLL.

    Wenn man auf NULL-Zeiger zugreift ist das eben nicht gesund 😉



  • Von der Funktion GetProcAdress() habe ich gelesen. Jedoch konnte ich als C++Newbie echt nicht wirklich was damit anfangen. Gibt es dazu irgenwelche Tutorials oder gut nachvollziebare Beispiele?

    Ich habe leider echt gar keinen schimmer, wie das Programm diesbezüglich organisiert sein muss... 😞

    Was ich bisher wohl Verstanden habe ist, dass die Dll wohl geladen ist aber die genauen Speicherorte der Funktionen offenbar nicht bekannt sind. Richtig? 😕



  • Schaffst du es allen ernstes nicht, dir ein Beispiel für GetProcAddress() zu ergoogeln?
    (Dazu muss man es Google-sei-dank nichtmal richtig schreiben, Google findet es auch mit einem "d")



  • OK die Formulierung war vielleicht etwas ungeeignet. Google-sei-dank habe ich in den letzten drei Tagen sehr sehr viele Beispiele gefunden. Aber durch 'Google-sei-dank' bekommt man leider weder C++ Kenntnisse noch eine halbwegs vernünftige für mich verständliche Erklärung was man dem Compiler, Linker, etc. zufüttern muss um eine DLL zu laden und eine Funktion daraus auf zu rufen.Ich mag nun mal learning by doing...

    @hustbaer
    Ich habe tatsächlich noch mal nach 'GetProcAddress beispiel' gegoogled. Dabei unter anderem diese Seite gefunden:
    http://msdn.microsoft.com/de-de/library/64tkc9y5(v=vs.80).aspx
    aber was genau sagt mir das?

    über den Zusammenhang
    von LoadLibrary()
    und GetProcAddress()
    und eventuell nötige Pointer
    aus? 🙄

    Weißt du ich habe mich hier angemeldet um mehr über C++ zu lernen bzw. meine bislang vorhandenen C-Kenntnisse zu erweitern und mit Leuten in Kontakt zu treten die vielleicht einfach auch meine Interessen teilen. Oder einfach was drauf haben und so herzensgut sind mir zu helfen!

    Ich meine les dir mal deinen Beitrag durch tu es einfach! Fällt dir etwas auf? Im Prinzip hast du tatschächlich nichts besseres zu tun, als mir zu sagen wie blöd ich doch offenbar bin. Unerfahren mit C++? ja! 🙂 Direkt nach dem Aufstehen noch nicht wach genug um ohne Rechtschreibefehler zu posten? ja! Vielleicht sogar manchmal so legastetisch veranlagt, dass ich offensichtliche Hinweise überlese 🙂 Aber zu dumm um Buchstaben in eine Suchleiste einzugeben? Nein! 😉
    Ganz ehrlich, Jemandem der gleich so losschießt traue ich persönlich absolut gar nichts zu! Nicht mal das er in der Lage ist mir zu helfen oder etwas zu erklären. Aber für den Fall, dass ich irgendwann mal Hilfe brauche bei Copy und Paste, weiß ich ja wo ich dich finde. Die dazu nötigen Parameter hast du nämlich echt eindrucksvoll geschildert 😉



  • So und ein weiterer Tag ging ins Land... ich habe heute Das Programm umgeschrieben nach meinem Wissen angepasst auf folgende Quelle:
    http://msdn.microsoft.com/de-de/library/64tkc9y5.aspx

    Das Problem ist nun, dass die funktion nicht geladen wird, also die Bedingung

    if (!mpusbgetdllversion)
    

    erfüllt ist...

    mpusbapi.c

    /*********************************************************************
     *
     *                Example 01 - Load-time Linking
     *
     *********************************************************************
     * FileName:        mpusbapi.cpp
     * Dependencies:    None
     * Compiler:        DevC++ 4.9.9.2
     * Company:         Copyright (C) 2011 P_Engineering
     *
     * Software License Agreement
     *
     *Use it or die!
     *
     * THIS SOFTWARE IS PROVIDED IN AN “AS IS” CONDITION. NO WARRANTIES,
     * WHETHER EXPRESS, IMPLIED OR STATUTORY, INCLUDING, BUT NOT LIMITED
     * TO, IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
     * PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. THE COMPANY SHALL NOT,
     * IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL OR
     * CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER.
     *
     * Author               Date        Comment
     *~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
     * Sören Reitz       10.08.11
     ********************************************************************/
    
    //---------------------------------------------------------------------------
    
    #include <stdio.h>
    #include <windows.h>
    #include <string.h>
    #include <setupapi.h>
    #include <initguid.h>
    #include <winioctl.h>
    #include "mpusbapi.h"                  // MPUSBAPI Header File
    #include <cstdlib>
    #include <iostream>
    
    //---------------------------------------------------------------------------
    //#pragma argsused
    
    // Global Vars
    char vid_pid[]= "vid_04d8&pid_000c";    // Default Demo Application Firmware
    char out_pipe[]= "\\MCHP_EP1";
    char in_pipe[]= "\\MCHP_EP1";
    
    DWORD temp;
    
    HANDLE myOutPipe;
    HANDLE myInPipe;
    HANDLE myRueckgabewert;
    typedef DWORD (CALLBACK *MPUSBGetDLLVersion)(void);
    HINSTANCE hDLL;               // Handle to DLL
    MPUSBGetDLLVersion mpusbgetdllversion;    // Function pointer
    
    //---------------------------------------------------------------------------
    // Prototypes
    void GetSummary(void);
    
    //---------------------------------------------------------------------------
    
    int main(int argc, char* argv[])
    {
        BOOLEAN bQuit;
        DWORD selection;
        bQuit = false;
    
    hDLL=LoadLibrary("mpusbapi.dll");
    
        if (hDLL != NULL)
        { 
            printf("dll geladen\r\n");
            mpusbgetdllversion = (MPUSBGetDLLVersion)GetProcAddress(hDLL,
                                               "DLLFunc1");
    
       if (!mpusbgetdllversion)
       {
        printf("fehler beim laden der Addresse");
       }
    
       else
       {
    
        // Always a good idea to initialize the handles
        myOutPipe = myInPipe = INVALID_HANDLE_VALUE;
    
        printf("Microchip Technology Inc., 2004\r\n");
        printf("===============================\r\n");
        while(!bQuit)
        {
            printf("Select an option\r\n");
            printf("[1] Get MPUSBAPI Version\r\n");
            printf("[2] Summarize Instances\r\n");
            printf("[3] -\r\n");
            printf("[4] Quit\r\n>>");
            scanf("%d",&selection);
    
            switch(selection)
            {
                case 1:
    
                    temp = mpusbgetdllversion();
                    printf("MPUSBAPI Version: %d.%d\r\n",HIWORD(temp),LOWORD(temp));
                    break;
                case 2:
                    GetSummary();
                    break;
                case 3:
                    // Place Holder
                    break;
                case 4:
                    bQuit = true;
                    break;
                default:
                    break;
            }// end switch
    
            fflush(stdin);printf("\r\n");
        }//end while
    
        // Always check to close all handles before exiting!
        if (myOutPipe != INVALID_HANDLE_VALUE) MPUSBClose(myOutPipe);
        if (myInPipe != INVALID_HANDLE_VALUE) MPUSBClose(myInPipe);
        myOutPipe = myInPipe = INVALID_HANDLE_VALUE;
    }
    }
        return 0;
    }//end main
    
    //---------------------------------------------------------------------------
    
    void GetSummary(void)
    {
        HANDLE tempPipe = INVALID_HANDLE_VALUE;
        DWORD count = 0;
        DWORD max_count;
    
        max_count = MPUSBGetDeviceCount(vid_pid);
    
        printf("\r\n%d device(s) with %s currently attached\r\n",max_count,vid_pid);
    
        // Note:
        // The total number of devices using the generic driver could be
        // bigger than max_count. They could have different vid & pid numbers.
        // This means if max_count is 2, the valid instance index do not
        // necessary have to be '0' and '1'.
        //
        // Below is a sample code for searching for all valid instance indexes.
        // MAX_NUM_MPUSB_DEV is defined in _mpusbapi.h
    
        count = 0;
        for(int i = 0; i < MAX_NUM_MPUSB_DEV; i++)
        {
            tempPipe = MPUSBOpen(i,vid_pid,NULL,MP_READ,0);
            if(tempPipe != INVALID_HANDLE_VALUE)
            {
                printf("Instance Index # %d\r\n",i);
                MPUSBClose(tempPipe);
                count++;
            }
            if(count == max_count) break;
        }//end for
        printf("\r\n");
    
    }//end GetSummary
    
    //---------------------------------------------------------------------------
    

    mousbapi.h

    /*********************************************************************
     *
     *                  MPUSBAPI Library Version 1.00
     *
     *********************************************************************
     * FileName:        mpusbapi.h
     * Dependencies:    None
     * Compiler:        C++
     * Company:         Copyright (C) 2004 by Microchip Technology, Inc.
     *
     * Software License Agreement
     *
     * The software supplied herewith by Microchip Technology Incorporated
     * (the “Company”) for its PICmicro® Microcontroller is intended and
     * supplied to you, the Company’s customer, for use solely and
     * exclusively on Microchip PICmicro Microcontroller products. The
     * software is owned by the Company and/or its supplier, and is
     * protected under applicable copyright laws. All rights are reserved.
     * Any use in violation of the foregoing restrictions may subject the
     * user to criminal sanctions under applicable laws, as well as to
     * civil liability for the breach of the terms and conditions of this
     * license.
     *
     * THIS SOFTWARE IS PROVIDED IN AN “AS IS” CONDITION. NO WARRANTIES,
     * WHETHER EXPRESS, IMPLIED OR STATUTORY, INCLUDING, BUT NOT LIMITED
     * TO, IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
     * PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. THE COMPANY SHALL NOT,
     * IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL OR
     * CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER.
     *
     * Author               Date        Comment
     *~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
     * Ross Fosler          9/2/04      Implemented MPUSBGetDeviceLink()
     * Rawin Rojvanit       11/19/04    Original version 1.00 completed
     ********************************************************************/
    
    #ifndef _MPUSBAPI_H_
    #define _MPUSBAPI_H_
    
    #define	MPUSB_FAIL                  0
    #define MPUSB_SUCCESS               1
    
    #define MP_WRITE                    0
    #define MP_READ                     1
    
    // MAX_NUM_MPUSB_DEV is an abstract limitation.
    // It is very unlikely that a computer system will have more
    // then 127 USB devices attached to it. (single or multiple USB hosts)
    #define MAX_NUM_MPUSB_DEV           127
    
    //DWORD (*MPUSBGetDLLVersion)(void);
    
    DWORD (*MPUSBGetDeviceCount)(PCHAR pVID_PID);
    
    HANDLE (*MPUSBOpen)(DWORD instance,         // Input
                     PCHAR pVID_PID,            // Input
                     PCHAR pEP,                 // Input
                     DWORD dwDir,               // Input
                     DWORD dwReserved);         // Input <Future Use>
    
    DWORD (*MPUSBRead)(HANDLE handle,           // Input
                    PVOID pData,                // Output
                    DWORD dwLen,                // Input
                    PDWORD pLength,             // Output
                    DWORD dwMilliseconds);      // Input
    
    DWORD (*MPUSBWrite)(HANDLE handle,          // Input
                     PVOID pData,               // Input
                     DWORD dwLen,               // Input
                     PDWORD pLength,            // Output
                     DWORD dwMilliseconds);     // Input
    
    DWORD (*MPUSBReadInt)(HANDLE handle,        // Input
                       PVOID pData,             // Output
                       DWORD dwLen,             // Input
                       PDWORD pLength,          // Output
                       DWORD dwMilliseconds);   // Input
    
    BOOL (*MPUSBClose)(HANDLE handle);
    
    #endif
    

    Ich habe keine Ahnung woran es hapert... 😞



  • Hallo,

    heißt die Funktion denn wirklich "DllFunc1"?
    Am besten, du schaust dir die "mpusbapi.dll" mal mit dem DependencyWalker an.

    (Was ich jedoch überhaupt nicht verstehe, ist, warum in der "mpusbapi.h" nur Funktionszeiger definiert sind? Denn wenn dort normal die Funktionen deklariert wären, dann könntest du einfach die DLL statisch einbinden (ohne LoadLibrary)!)



  • Th69 danke für den Tipp! Der Dependecy Walker war der Schlüssel zum Erfolg! Die DLL war wohl mit dem Boreland c++compiler erstellt. Die Funktionen hatten je einen _davor deshalb konnten sie in der Vergangenheit auch nicht gefunden werden.

    Ich habe jetzt den Beispielcode dank der Hilfe des Forums zum laufen bekommen ich danke allen die mir dabei geholfen haben, indem sie mich mit Tipps versorgt haben. 😃 glücklich! 😃 sollte Bedarf an dem Quellcode liegen, einfach melden

    Grüße FaceForce



  • 👍

    P.S. "Orojekt" im Titel könntest du mal korrigieren...


Anmelden zum Antworten