W
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!