Dynamische DLL - kleiner Fehler nach Tutorial



  • Hallo,

    ich habe gerade das Builder Tutorial "DLL - Dynamic Link Library" anhand des Beispiels dynamische DLL durchgarbeitet. Ich habe allerdings zur Erzielung eines besseren Lerneffektes gleich eine eigene (sehr kleine) Funktion und eine eigene Test-Anwendung geschrieben / erstellt. Nun bekomme ich beim Erzeugen der Projekte die Fehlermeldung:

    [C++ Fehler] Unit1.cpp(52): E2031 Typumwandlung von 'int' nach 'void(int)' nicht zulässig

    in der Test-Anwendung, wo ich die dll-Funktion aufrufe:

    Wait(50);
    

    Da ich momentan vor Deklarationen, Definitionen, Schnittstellenfunktionen, Funktionszeigertypen etc. nicht mehr durchsehe, benötige ich Eure Hilfe den Fehler zu beseitigen und zu verstehen!

    Die Funktion soll einfach nur eine Wartezeit einfügen. Die DLL-zugehörige unit2 sieht so aus:

    //Project2.dll->Unit2
    #include <vcl.h>
    #include <windows.h>
    #pragma hdrstop
    
    #pragma argsused
    
    int WINAPI DllEntryPoint(HINSTANCE hinst, unsigned long reason, void* lpReserved)
    {   return 1;    }
    //---------------------------------------------------------------------------
    
    extern"C" __declspec(dllexport) void Wait(int W)	
    {   Sleep((int)W);
        Application->ProcessMessages();    }
    

    Die Import-Unit sieht so aus:

    // Project1.exe->Import.cpp
    //Import.h:
    #ifndef ImportH
    #define ImportH
    //---------------------------------------------------------------------------
    
    typedef void Wait(int W);
    
    Wait(W);
    
    #endif
    //===========================================================================
    //Import.cpp:
    #pragma hdrstop
    #include "Import.h"
    //---------------------------------------------------------------------------
    
    #pragma package(smart_init)
    
    void Wait(int W) 
    {   TWait* Wait; 
        HINSTANCE h = LoadLibrary("Project2.dll"); 
        if (h != 0)
            Wait = (TWait*)GetProcAddress(h, "_Wait");
        void Wait(int W); 
        FreeLibrary(h);    }
    

    Die Test-Anwendung sieht so aus:

    //Project1.exe->Unit1.cpp
    #include <vcl.h>
    #pragma hdrstop
    
    #include "Unit1.h"
    #include "Import.h"
    //---------------------------------------------------------------------------
    #pragma package(smart_init)
    #pragma resource "*.dfm"
    TForm1 *Form1;
    //---------------------------------------------------------------------------
    __fastcall TForm1::TForm1(TComponent* Owner)
    	: TForm(Owner)
    {}
    
    ...
    void __fastcall TForm1::Button2Click(TObject *Sender)
    {   Button1->Enabled= false;
        for (int i=1; i<100; i++)
        {   if (i<10) {    Label1->Caption= "0" + IntToStr(int(i));    }
            else if (i>9) {    Label1->Caption= IntToStr(int(i));    }
            Wait(50);    }
        Label1->Caption= "00";
        Button1->Enabled= true;    }
    

    Ich habe keine Ahnung, was ich falsch mache! 😞

    MfG



  • Hi,
    wo ist denn der TWait aus

    void Wait(int W)
    {   TWait* Wait;
    ...
    

    deklariert?



  • Machs mal so

    / Project1.exe->Import.cpp
    //Import.h:
    #ifndef ImportH
    #define ImportH
    //---------------------------------------------------------------------------
    
    typedef void TWait(int W); //das sollte ja wohl TWait sein
    
    //===========================================================================
    //Import.cpp:
    #pragma hdrstop
    #include "Import.h"
    //---------------------------------------------------------------------------
    
    #pragma package(smart_init)
    
    void Wait(int W)
    {   
        TWait* waitfnc; //es ist ungünstig eine interne Variable wie die Funktion zu benennen
        HINSTANCE h = LoadLibrary("Project2.dll");
        if (h != 0)
            waitfnc= (TWait*)GetProcAddress(h, "_Wait");
        waitfnc(W); //aufrufen nicht neu deklarieren
        FreeLibrary(h);    
    }
    
    #endif
    


  • Ich denke mal, lt. Tut wolltest du so etwas im *.h schreiben, nur halt angepasst an deine Funktion:

    typedef int TAddVals(int, int ); //Funktionszeigertyp. In diesem Fall hätte man auch einen Typen

    int AddVals(int x, int y); //Schnittstellen-Funktion.

    edit:
    Erstaunlich, wie lange ich brauche, um in einem einzigen Tut nachzuschlagen...



  • Danke für Eure Tips!

    @Braunstein:
    * Jaja, dieses kleine böse "Transponier'-Zeichen" (sprich T)... 👍
    * Die Variable hab' ich nun besser "WaitAdr" genannt, führt eindeutig zu weniger Verwirrungen.

    Und dann hatte ich wohl noch in Import.h / ~.cpp Deklaration der Schnittstellen-Fkt. und Aufruf der Dll-Fkt. vertauscht... perfekt ist das Chaos! 😃

    Außerdem hätte mir ruhig mal jemand den Hinweis geben können, dass ich in Import die windows.h includieren muss... 🙄 😃

    Habe fertig!



  • Darauf hättest du aufgrund der Fehlermeldungen ja auch selber kommen können. Ohne windows.h kein LoadLibrary, HINSTANCE etc. 🙂



  • Scho recht,

    nur wenn ich nach oben (Eröffnungs-Post) schaue, seh' ich bloß eine Fehlermeldung. 😞
    Das dem Compiler HINSTANCE, LoadLibrary etc nicht bekannt sind, wollte er mir erst heute sagen, nachdem er schön ausgeschlafen hatte und besser gelaunt war 🤡

    Das war jetzt aber nicht wirklich ne Kritik von mir, scheinbar hast Du's ja so verstanden... Darauf kann man wirklich allein kommen wenn's soweit ist! 👍


Anmelden zum Antworten