[gelöst]wXWidgets GUI mit Zugriff auf eine DLL



  • Hallo,

    Ich möchte ein GUI erstellen, welches Funktionen einer DLL aufruft.

    Zum erstellen der GUI habe ich wxDev-c++ benutzt, funktioniert soweit blendend. Jedoch ist es mir nicht möglich auf die DLL zuzugreifen. In einem anderen C++Programm konnte ich die DLL mit LoadLibrary() and GetProcAddress() laden, aber hier bekomme ich es einfach nicht gebacken! Ist das denn überhaupt im Rahmen einer solchen Anwendung möglich?

    ich habe folgende Dateien:
    versuchApp.cpp

    #include "versuchApp.h"
    #include "versuchFrm.h"
    
    IMPLEMENT_APP(versuchFrmApp)
    
    bool versuchFrmApp::OnInit()
    {
        versuchFrm* frame = new versuchFrm(NULL);
        SetTopWindow(frame);
        frame->Show();
        return true;
    }
    
    int versuchFrmApp::OnExit()
    {
    	return 0;
    }
    

    versuchApp.h

    #ifndef __VERSUCHFRMApp_h__
    #define __VERSUCHFRMApp_h__
    
    #ifdef __BORLANDC__
    	#pragma hdrstop
    #endif
    
    #ifndef WX_PRECOMP
    	#include <wx/wx.h>
    #else
    	#include <wx/wxprec.h>
    #endif
    
    class versuchFrmApp : public wxApp
    {
    	public:
    		bool OnInit();
    		int OnExit();
    };
    #endif
    

    versuchFrm.cpp

    #include "versuchFrm.h"
    
    ////Header Include Start
    ////Header Include End
    
    //----------------------------------------------------------------------------
    // versuchFrm
    //----------------------------------------------------------------------------
    //Add Custom Events only in the appropriate block.
    //Code added in other places will be removed by wxDev-C++
    ////Event Table Start
    BEGIN_EVENT_TABLE(versuchFrm,wxFrame)
    	////Manual Code Start
    	////Manual Code End
    
    	EVT_CLOSE(versuchFrm::OnClose)
    	EVT_MENU(ID_MNU_SCHLIESSEN, versuchFrm::FensterSchliessen)
    	EVT_MENU(ID_MNU_LED1AN, versuchFrm::LED1an)
    	EVT_MENU(ID_MNU_LED1AUS, versuchFrm::LED1aus)
    END_EVENT_TABLE()
    ////Event Table End
    
    versuchFrm::versuchFrm(wxWindow *parent, wxWindowID id, const wxString &title, const wxPoint &position, const wxSize& size, long style)
    : wxFrame(parent, id, title, position, size, style)
    {
    	CreateGUIControls();
    }
    
    versuchFrm::~versuchFrm()
    {
    }
    
    void versuchFrm::CreateGUIControls()
    {
    
    	WxMenuBar1 = new wxMenuBar();
    	wxMenu *ID_MNU_DATEI_Mnu_Obj = new wxMenu(0);
    	ID_MNU_DATEI_Mnu_Obj->Append(ID_MNU_SCHLIESSEN, wxT("&Schließen"), wxT("Schließt Datei"), wxITEM_NORMAL);
    	WxMenuBar1->Append(ID_MNU_DATEI_Mnu_Obj, wxT("&Datei"));
    
    	wxMenu *ID_MNU_HARDWARE_Mnu_Obj = new wxMenu(0);
    
    	wxMenu *ID_MNU_LEDS_Mnu_Obj = new wxMenu(0);
    	ID_MNU_LEDS_Mnu_Obj->Append(ID_MNU_LED1AN, wxT("LED1an"), wxT(""), wxITEM_NORMAL);
    	ID_MNU_LEDS_Mnu_Obj->Append(ID_MNU_LED1AUS, wxT("LED1aus"), wxT(""), wxITEM_NORMAL);
    	ID_MNU_LEDS_Mnu_Obj->Append(ID_MNU_SUBMENUITEM8_1008, wxT("SubMenuItem8"), wxT(""), wxITEM_NORMAL);
    	ID_MNU_HARDWARE_Mnu_Obj->Append(ID_MNU_LEDS, wxT("LEDs"), ID_MNU_LEDS_Mnu_Obj);
    	WxMenuBar1->Append(ID_MNU_HARDWARE_Mnu_Obj, wxT("Hardware"));
    	SetMenuBar(WxMenuBar1);
    
    	SetTitle(wxT("versuch"));
    	SetIcon(wxNullIcon);
    	SetSize(8,8,320,334);
    	Center();
    
    	////GUI Items Creation End
    }
    
    void versuchFrm::OnClose(wxCloseEvent& event)
    {
    	Destroy();
    }
    
    /*
     * FensterSchliessen
     */
    void versuchFrm::FensterSchliessen(wxCommandEvent& event)
    {
    	Close();
    }
    
    /*
     * LED1an
     */
    void versuchFrm::LED1an(wxCommandEvent& event)
    {
    //	main(1);
    }
    
    /*
     * LED1aus
     */
    void versuchFrm::LED1aus(wxCommandEvent& event)
    {
    	// insert your code here
    }
    

    versuchFrm.h

    #ifndef __VERSUCHFRM_H__
    #define __VERSUCHFRM_H__
    
    #ifdef __BORLANDC__
    	#pragma hdrstop
    #endif
    
    #ifndef WX_PRECOMP
    	#include <wx/wx.h>
    	#include <wx/frame.h>
    #else
    	#include <wx/wxprec.h>
    #endif
    
    //Do not add custom headers between 
    //Header Include Start and Header Include End.
    //wxDev-C++ designer will remove them. Add custom headers after the block.
    ////Header Include Start
    #include <wx/menu.h>
    ////Header Include End
    //extern "C"
    //{
    
    //}
    ////Dialog Style Start
    #undef versuchFrm_STYLE
    #define versuchFrm_STYLE wxCAPTION | wxSYSTEM_MENU | wxMINIMIZE_BOX | wxCLOSE_BOX
    ////Dialog Style End
    
    class versuchFrm : public wxFrame
    {
    	private:
    		DECLARE_EVENT_TABLE();
    
    	public:
    		versuchFrm(wxWindow *parent, wxWindowID id = 1, const wxString &title = wxT("versuch"), const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxDefaultSize, long style = versuchFrm_STYLE);
    		virtual ~versuchFrm();
    		void FensterSchliessen(wxCommandEvent& event);
    		void LED1an(wxCommandEvent& event);
    		void LED1aus(wxCommandEvent& event);
    
    	private:
    		//Do not add custom control declarations between
    		//GUI Control Declaration Start and GUI Control Declaration End.
    		//wxDev-C++ will remove them. Add custom code after the block.
    		////GUI Control Declaration Start
    		wxMenuBar *WxMenuBar1;
    		////GUI Control Declaration End
    
    	private:
    		//Note: if you receive any error with these enum IDs, then you need to
    		//change your old form code that are based on the #define control IDs.
    		//#defines may replace a numeric value for the enum names.
    		//Try copy and pasting the below block in your old form header files.
    		enum
    		{
    			////GUI Enum Control ID Start
    			ID_MNU_DATEI = 1001,
    			ID_MNU_SCHLIESSEN = 1002,
    			ID_MNU_HARDWARE = 1003,
    			ID_MNU_LEDS = 1004,
    			ID_MNU_LED1AN = 1005,
    			ID_MNU_LED1AUS = 1006,
    			ID_MNU_SUBMENUITEM8_1008 = 1008,
    
    			////GUI Enum Control ID End
    			ID_DUMMY_VALUE_ //don't remove this value unless you have other enum values
    		};
    
    	private:
    		void OnClose(wxCloseEvent& event);
    		void CreateGUIControls();
    };
    
    #endif
    


  • Hallo, du kannst deine Bibliothek über die Klasse wxDynamicLibrary (http://docs.wxwidgets.org/stable/wx_wxdynamiclibrary.html#wxdynamiclibrary) laden.



  • Owei, jetzt kommt die Stelle, an der es krimminell wird, weil ich zugegebener Maßen erst mit Objektorientiertem Programmieren beginne... 🙄

    folgendes habe ich mir bislang an Hintergrund erarbeiten können:

    1.Die Klasse selbst ist in der Bibiliotek "wx/dynlib.h" hinterlegt und muss mit

    #include<wx/dynlib.h>
    

    geladen werden.

    2.Vor dem Bibiliotheksaufruf, sollte

    #define wxUSE_DYNLIB_CLASS=1
    

    stehen, damit die Header überhaupt geladen werden kann.

    Ist das soweit richtig? Aus dem guten alten C, meine ich mich zu erinnern, dass jedes Programm eine main-Funktion braucht. Ist das bei C++ generell oder nur bei wxWidgets anders?

    Beste grüße und ein Danke an Alle die sich Zeit nehmen mir zu helfen



  • Naja, OOP ist ja so ne Sache, man sollte es doch schon ein wenig beherrschen bevor man mit solchen Frameworks beginnt.

    Ich muß gestehen, bei mir ist wxWidgets ein wenig her, aber ich versuche dir mal soweit zu helfen wie ich kann.

    Du mußt die

    #include <wx/dynlib.h>
    

    inkludieren, damit du mit der Klasse überhaupt arbeiten kannst. Soweit steht auch das mit dem define in der Dokumentation damit dies benötigt wird.

    Das ist korrekt, die Main Funktion wird in wxWidgets durch das Makro IMPLEMENT_APP realisiert. Hier wird im Prinzip eine Instanz (die App Ableitung) deines Programmes gestartet.

    Ein guter Tipp, falls du da noch nichts in der richtung hast würde ich einfach mal die Tutorials unter http://zetcode.com/tutorials/wxwidgetstutorial/ oder irgendwelchen andere durcharbeiten. Dies kann dir unter Umständen sehr viel helfen.



  • Ja es ist wohl wirklich etwas größenwahnsinnig gleich mit einer GUI zu starten. Mit OOP bin ich ja nicht ganz unvertraut, wir hatten in der FH OOP jedoch mit MATLAB und das ist für meinen Geschmack etwas ununiversell dazu bin ich der Meinung wer C sagt sollte auch C++ sagen und die Leber wächst mit der größe ihrer Aufgaben 😉 Die Beste Hilfe bekomme ich mit Sicherheit hier...

    Mein größtes Problem ist, dass ich mit der wxWidgets-Doku nicht klar komme :(In der Vergangenheit, fand sich bislang immer irgendwo im Netz ein Beispielcode, den man irgendwie verstehen konnte... Diese 'Member' sind dann Nachrichten die benötigt sind um die DLL zu laden? Muss mich da erstmal langsam ranhangeln, bevor ich wieder blindlinks irgendwo Code in mein fast fertiges Programm schreibe wo er dann nichts zu suchen hat^^

    #define wxUSE_DYNLIB_CLASS
    #include <wx/dynlib.h>
    

    habe ich jetzt bei versuchFrm.h zugefügt:

    #ifndef __VERSUCHFRM_H__
    #define __VERSUCHFRM_H__
    
    #ifdef __BORLANDC__
        #pragma hdrstop
    #endif
    
    #ifndef WX_PRECOMP
        #include <wx/wx.h>
        #include <wx/frame.h>
    #else
        #include <wx/wxprec.h>
    #endif
    //Do not add custom headers between 
    //Header Include Start and Header Include End.
    //wxDev-C++ designer will remove them. Add custom headers after the block.
    ////Header Include Start
    #include <wx/menu.h>
    ////Header Include End
          #define wxUSE_DYNLIB_CLASS
          #include <wx/dynlib.h> 
    ////Dialog Style Start
    #undef versuchFrm_STYLE
    #define versuchFrm_STYLE wxCAPTION | wxSYSTEM_MENU | wxMINIMIZE_BOX | wxCLOSE_BOX
    ////Dialog Style End
    
    class versuchFrm : public wxFrame
    .
    .
    .
    

    da bei versuchFrm.cpp

    void versuchFrm::LED1an(wxCommandEvent& event)
    {
    //hier soll auf die Funktionen der DLL zugegriffen werden, um die LED an einem 
    //selbsgebastelten USB-Device zum leuchten zu bringen...
    }
    

    die Funktionen der DLL benötigt werden 🙂 der nächste Schritt ist sicherlich irgendwo einen constructor einzubauen oder?

    soweit ich mich jetzt richtig belesen habe wäre das:

    wxDynamicLibrary::wxDynamicLibrary
    

    Ich hoffe meine ganzen Fragen sind OK und ich hoffe auch, dass man merkt das ich mich schon etwas mit der Thematik beschäfftigt habe 🙂



  • Was meinst du in diesem Fall mit Member? Wie gesagt, ich lege dir nahe erst einmal das OOP in C++ nach zu holen und dann einige Einstieg Tutorials für wxWidgets durch zu arbeiten. Ich kann dir hier mal einen Link geben, dort habe ich die wxDynamicLibrary ebenfalls genutzt.
    https://github.com/guenni81/wxpluginexample



  • also in der doku steht:

    Members

    wxDynamicLibrary::wxDynamicLibrary
    wxDynamicLibrary::CanonicalizeName
    wxDynamicLibrary::CanonicalizePluginName
    wxDynamicLibrary::Detach
    wxDynamicLibrary::GetSymbol
    wxDynamicLibrary::GetSymbolAorW
    wxDynamicLibrary::GetProgramHandle
    wxDynamicLibrary::HasSymbol
    wxDynamicLibrary::IsLoaded
    wxDynamicLibrary::ListLoaded
    wxDynamicLibrary::Load
    wxDynamicLibrary::Unload

    Das meinte ich mit Member, ansonsten werde ich sehen, dass ich deinen Ratschlag irgendwie befolge und mich erst einmal fitter in OOP machen werde. Falls ich fragen habe kann ich mich bestimmt melden? danke jedenfalls für die hilfe bis hier hin.



  • Achso, jetzt weiß ich was du mit den Membern gemeint hast. Im Prinzip die Funktionen und Eigenschaften der Klasse.
    Ist eine gute Entscheidung, dann wird das ganze auch ein wenig einfacher...
    Natürlich, hier im Forum bekommt man immer soweit es möglich ist geholfen. 🙂



  • So gut Ding will Weile haben 🙂 ich bin nun etwas weiter gekommen und habe es sogar geschafft die DLL zu laden und festzustellen, ob die gesuchten Symbole(Funktionen) vorhanden sind hurra!

    also:

    bool 	Load (const wxString &name, int flags=wxDL_DEFAULT)
    bool 	HasSymbol (const wxString &name) const
    

    Ließen sich Problemlos aufrufen.

    Der letzte Trick ist dann noch irgendwie auf die Funktionen in der DLL zuzugreifen.

    Soweit ich das bislang richtig durchschaut habe, muss ich mit Zeigern auf die Funktionen der Dll zugreifen. Die Addressen der Funktionen bekomme ich mit

    void * 	GetSymbol (const wxString &name, bool *success=0) const
    

    Stimmt der Fahrplan soweit? Wäre schön wenn mich mal jemand bestätigen könnte 🙂



  • Korrekt, der Fahrplan stimmt soweit! 😃



  • Hi guenni, da du der einzige warst der auf meinen Beitrag geantwortet hat, ein dickes dankeschön nur an DICH! 🙂

    Sicherlich war der Tipp mit den gegebenen Memberfunktionen der beste überhaupt! Aber da ich mich entschlossen habe mehr über C++ in allgemeinen zu lernen, Habe ich mal meine eigene Klasse zum laden dieser DLL geschrieben...

    (Mit Black Jack und Nutten...Ach vergiss die Klasse und Black Jack!) 😃

    Nein im ernst! Danke für den Support danke für das Beispiel, welches anschaulich war 🙂


Anmelden zum Antworten