[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::UnloadDas 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