[wxWidgets] DLL + EXE



  • Hey Leute!
    Ich bins wieder udn zwar habe ich eine kleine frage^^
    Hab ein Beispiel gefunden wie man eine DLL erstellen kann und diese benutzen.
    Hab das beispiel aus dem englischen wxWidgets Forum.

    Die ersten beiden sind die Includes
    Die zwei danach die dll
    Und die restlichen 4 die api.

    Die include Header:
    Plugin.h

    #ifndef PLUGIN_H
    #define PLUGIN_H
    
    #include <wx/wx.h>
    
    //declare the main plugin entry function,
    //a DLL entry function and a wxApp for the DLL
    //Creating the wxApp and DLL entry may not be needed when using a
    //wxWidgets DLL for host and plugin as they should share the same wxApp
    //In this case everything was linked statically
    #define IMPLEMENT_PLUGIN(name)														\
    	extern "C" __declspec(dllexport) Plugin* CreatePlugin(){return new name; }		\
    																					\
    	class nameDLLApp : public wxApp													\
    	{																				\
    		bool OnInit() {return true;}												\
    	};																				\
    	IMPLEMENT_APP_NO_MAIN(nameDLLApp)												\
    																					\
    	BOOL APIENTRY DllMain( HANDLE hModule,											\
                           DWORD  ul_reason_for_call,									\
                           LPVOID lpReserved											\
    	                                         )										\
    	{																				\
    		    switch (ul_reason_for_call)												\
    			{																		\
                    case DLL_PROCESS_ATTACH:											\
                    {       wxSetInstance((HINSTANCE)hModule);							\
                            int argc = 0;												\
                            char **argv = NULL;											\
                            wxEntryStart(argc, argv);									\
                    }																	\
                    break;																\
    																					\
                    case DLL_THREAD_ATTACH:												\
                    break;																\
    																					\
                    case DLL_THREAD_DETACH:												\
                    break;																\
    																					\
                    case DLL_PROCESS_DETACH:											\
                     wxEntryCleanup();													\
                    break;																\
    			}																		\
    		return TRUE;																\
    	}																				\
    
    //define the interface for the plugin
    class Plugin : public wxEvtHandler
    {
    public:
    	virtual void PerformTasks()=0;
    	virtual char* GetName()=0;
    	virtual wxPanel* GetGUIPanel(wxWindow* parent)=0;
    };
    //define a function pointer type for convenience
    #ifndef __PLUGIN_FUNCTION
    #define __PLUGIN_FUNCTION
    typedef Plugin* ( *CreatePlugin_function)();
    #endif //__PLUGIN_FUNCTION
    
    #endif
    

    Plugin.cpp

    #include "Plugin.h"
    
    /*IMPLEMENT_APP_NO_MAIN(wxDLLApp)
    
    BOOL APIENTRY DllMain( HANDLE hModule,
                           DWORD  ul_reason_for_call,
                           LPVOID lpReserved
                                             )
    {
            switch (ul_reason_for_call)
            {
                    case DLL_PROCESS_ATTACH:
                    {       wxSetInstance((HINSTANCE)hModule);
                            int argc = 0;
                            char **argv = NULL;
                            wxEntryStart(argc, argv);
                    }
                    break;
    
                    case DLL_THREAD_ATTACH:
                    break;
    
                    case DLL_THREAD_DETACH:
                    break;
    
                    case DLL_PROCESS_DETACH:
                     wxEntryCleanup();
                    break;
            }
        return TRUE;
    }*/
    

    Nun die DLL

    MyPlugin.h

    #include <Plugin.h>
    //define the actual plugin
    class MyPlugin : public Plugin
    {
    public:
    	virtual void PerformTasks();
    	virtual char* GetName();
    	virtual wxPanel* GetGUIPanel(wxWindow* parent);
    
    	void OnButton(wxCommandEvent& e);
    };
    

    MyPlugin.cpp

    #include "MyPlugin.h"
    //call the macro to implement DLL entry function and the function to return our actual plugin object
    IMPLEMENT_PLUGIN(MyPlugin)
    
    void MyPlugin::PerformTasks()
    {
    	wxMessageBox("I would if I could...");
    }
    char* MyPlugin::GetName()
    {
    	return "MyTest";
    }
    wxPanel* MyPlugin::GetGUIPanel(wxWindow* parent)
    {
    	wxPanel* p2 = new wxPanel(parent,-1);
    	p2->SetBackgroundColour(*wxBLACK);
    
    	wxBoxSizer* box = new wxBoxSizer(wxHORIZONTAL);
    	wxButton* b = new wxButton(p2,1000,"Some action in the plugin");
    
    	//Use connect in this case as static event tables won't work
    	//As Plugin is derived from wxEvtHandler you can catch events in this Plugin
    	b->Connect( 1000,
        wxEVT_COMMAND_BUTTON_CLICKED,
        wxCommandEventHandler(MyPlugin::OnButton),NULL,this
    	);
    
    	box->Add(b,0,wxALIGN_CENTER,0);
    	p2->SetSizer(box);
    	return p2;
    }
    void MyPlugin::OnButton(wxCommandEvent& e)
    {
    	wxMessageBox("Doing some action");
    }
    

    Zu guter letzt die Exe Anwendung:
    HostApp.h

    #pragma once
    #include <wx/wx.h>
    class HostApp : public wxApp
    {
    public:
        HostApp();
        virtual ~HostApp();
        virtual bool OnInit();
    };
    
    DECLARE_APP(HostApp)
    

    HostApp.cpp

    #include "HostApp.h"
    #include "HostFrame.h"
    
    IMPLEMENT_APP(HostApp)
    
    // ============================================================================
    // implementation
    // ============================================================================
    HostApp::HostApp()
    {
    }
    
    HostApp::~HostApp()
    {
    }
    
    bool HostApp::OnInit()
    {
    	HostFrame *frame = new HostFrame(_("wxWidgets"),
    	wxPoint(50, 50), wxSize(400, 300));
    
    	frame->Show(TRUE);
    	SetTopWindow(frame);
    
    	return TRUE;
    }
    

    HostFrame.h

    #pragma once
    #include <wx/wx.h>
    #include <wx/notebook.h>
    class HostFrame : public wxFrame
    {
    	wxNotebook* m_notebook;
    	wxBoxSizer* box;
    public:
    	HostFrame(const wxString& title, const wxPoint& pos, const wxSize& size);
    	virtual ~HostFrame();
    
    private:
    	DECLARE_CLASS(HostFrame)
    
    	void OnDoit(wxCommandEvent& e);
    	DECLARE_EVENT_TABLE()
    };
    

    HostFrame.cpp

    #include "HostApp.h"
    #include "HostFrame.h"
    
    #include <wx/dynlib.h>
    //include the plugin definition
    #include <Plugin.h>
    // ----------------------------------------------------------------------------
    // constants
    // ----------------------------------------------------------------------------
    enum
    {
    	ID_DOIT = 1
    };
    IMPLEMENT_CLASS(HostFrame, wxFrame)
    
    BEGIN_EVENT_TABLE(HostFrame, wxFrame)
    	EVT_BUTTON(ID_DOIT, HostFrame::OnDoit)
    END_EVENT_TABLE()
    
    // ----------------------------------------------------------------------------
    // main frame
    // ----------------------------------------------------------------------------
    HostFrame::HostFrame(const wxString& title, const wxPoint& pos, const wxSize& size)
    : wxFrame((wxFrame *)NULL, -1, title, pos, size)
    {
    	box = new wxBoxSizer(wxVERTICAL);
    	wxButton* b = new wxButton(this,ID_DOIT,"Doit");
    	m_notebook = new wxNotebook(this,-1);
    
    	wxPanel* dummy = new wxPanel(m_notebook,-1);
    	m_notebook->AddPage(dummy,"Dummy");
    
    	box->Add(b,0,wxEXPAND,0);
    	box->Add(m_notebook,1,wxEXPAND,0);
    
    	SetSizer(box);
    	Layout();
    }
    
    HostFrame::~HostFrame()
    {
    }
    
    void HostFrame::OnDoit(wxCommandEvent& e)
    {
    	//Load the plugin
    	wxDynamicLibrary dll("Plugin.dll");
    	if(dll.IsLoaded())
    	{
    		//Create a valid function pointer using the function pointer type in plugin.h
    		wxDYNLIB_FUNCTION(CreatePlugin_function,CreatePlugin,dll);
    		//check if the function is found
    		if(pfnCreatePlugin)
    		{
    			//Important: Use Detach(), otherwise the DLL will be unloaded once the wxDynamibLibrary object
    			//goes out of scope
    			dll.Detach();
    			//Create the plugin
    			Plugin* plugin = pfnCreatePlugin();
    			//call some method in it
    			plugin->PerformTasks();
    			wxString str = plugin->GetName();
    			//get and add the plugin interface
    			m_notebook->AddPage(plugin->GetGUIPanel(m_notebook),str);
    		}
    	}
    
    }
    

    So nun meine fragen zum Sehen&Verstehen^^

    1.) Wieso definiert der IMPLEMENT_PLUGIN() da? Hat wx keine eigenen Makros dafür? Oder muss man sich hier selbst um die Unabhängigkeit von Platformen kümmern?
    2.) IMPLEMENT_APP_NO_MAIN(nameDLLApp) braucht erklärungs Bedarf^^
    3.) Wozu IMPLEMENT_CLASS(HostFrame, wxFrame)?
    4.) "typedef Plugin* ( *CreatePlugin_function)();" Was bewirkt dieser Code?
    5.) Warum steht bei der Plugin.cpp die methode IMPLEMENT_APP_NO_MAIN in Kommentaren?
    6.) Könnte mir jemand Links zu documentationen der wxKlassen die für sowas genutzt werden?
    7.) Warum muss class Plugin : public wxEvtHandler davon ableiten?
    8.) Muss man in der dll die Eventhandler per connect machen?

    So das wären vorerst alle^^
    Eröffnen sich sicher noch paar xD

    Danke im Vorraus^^
    Mfg Wikinger75!


Anmelden zum Antworten