DLLプロジェクトを作成し、プリプロセッサディレクティブを指定します(例:/ DIFLOOR_EXPORTS_COMMONPLUGINBASE(このプリプロセッサ変数はDLLプロジェクトでのみ))
次に、クラスをインポートするかエクスポートするかを指定するヘッダーを作成します。
CommonPluing.h
#ifndef _COMMONPLUGIN_H
#define _COMMONPLUGIN_H
#if defined(__WXMSW__)
#ifdef IFLOOR_EXPORTS_COMMONPLUGINBASE
#define IFLOOR_API_COMMONPLUGINBASE __declspec(dllexport)
#else
#define IFLOOR_API_COMMONPLUGINBASE __declspec(dllimport)
#endif
#else
#define IFLOOR_API_COMMONPLUGINBASE
#endif
#endif // _COMMONPLUGIN_H
次に、エクスポートしたクラスを作成し、最初のヘッダーから指定子を追加します。
CommonConfigWindowBase.h
class IFLOOR_API_COMMONPLUGINBASE CommonConfigWindowBase : public wxPanel
{
DECLARE_DYNAMIC_CLASS(CommonConfigWindowBase)
public:
/// Constructors
CommonConfigWindowBase();
CommonConfigWindowBase(wxWindow *parent,
wxWindowID winid = wxID_ANY,
const wxPoint& pos = wxDefaultPosition,
const wxSize& size = wxDefaultSize,
long style = wxTAB_TRAVERSAL | wxNO_BORDER,
const wxString& name = wxPanelNameStr);
/// Pseudo ctor
bool Create(wxWindow *parent,
wxWindowID winid = wxID_ANY,
const wxPoint& pos = wxDefaultPosition,
const wxSize& size = wxDefaultSize,
long style = wxTAB_TRAVERSAL | wxNO_BORDER,
const wxString& name = wxPanelNameStr);
virtual ~CommonConfigWindowBase();
/// Reads config from the effect
virtual bool ReadConfig(){return true;}
/// Saves config to the effect
virtual bool SaveConfig(){return true;}
};
メインの実行可能ファイルから呼び出し可能なエクスポートされた関数を作成します(ラッパークラスを作成し、wxWindow *を返すメソッドを呼び出すことができます)。プラグインオブジェクトを作成および削除するには、エクスポートされたメソッドが必要です。また、あなたは!!!が必要です 仮想デストラクタ!!! エクスポートされたオブジェクトとウィンドウ用。したがって、SportEffectPluginにwxWindow * CreateConfigWindow(wxWindow * parent)メソッドが含まれていると仮定します。
Exports.cpp
#include "stdwx.h"
#include "CommonConfigWindowBase.h"
IFLOOR_API_COMMONPLUGINBASE IFloorEffectPluginBase * CreatePlugin(const wxString& sBasePath, iFloorBlobVector * blobs)
{
return new SportEffectPlugin(sBasePath, blobs);
}
IFLOOR_API_COMMONPLUGINBASE void DeletePlugin(IFloorEffectPluginBase * plugin)
{
wxDELETE(plugin);
}
次に、メインアプリでDLLをロードします(必要に応じて次のコードを採用する必要があります)。
Loader.cpp
bool IFloorSystem::LoadPlugins(bool forceProgramPath)
{
if (!m_DefaultPlugin)
{
m_DefaultPlugin = new DefaultEffectPlugin(GetDefaultGraphicsPath());
RegisterEffectPlugin(m_DefaultPlugin);
}
wxFileName fn;
fn.AssignDir(GetPluginsPath(forceProgramPath));
wxLogDebug(wxT("%s"), fn.GetFullPath().data());
fn.AppendDir(wxT("effects"));
wxLogDebug(wxT("%s"), fn.GetFullPath().data());
if (!fn.DirExists())
return false;
wxDir dir(fn.GetFullPath());
if (!dir.IsOpened())
return false;
// scan for plugins
wxString filename;
wxString ext = wxT("*.dll"); // TODO: change ext for different platforms
bool bFound = dir.GetFirst(&filename, ext, wxDIR_FILES);
while (bFound)
{
fn.SetFullName(filename);
wxDynamicLibrary * dll = new wxDynamicLibrary(fn.GetFullPath());
if (dll->IsLoaded())
{
wxDYNLIB_FUNCTION(CreatePlugin_function, CreatePlugin, *dll);
if (pfnCreatePlugin)
{
IFloorEffectPluginBase* plugin = pfnCreatePlugin(GetDefaultGraphicsPath(), &IFloorStorage::Instance().GetBlobs());
RegisterEffectPlugin(plugin);
m_DllList.Append(dll);
m_MapPluginsDll[plugin] = dll;
}
else
wxDELETE(dll);
}
bFound = dir.GetNext(&filename);
}
return true;
}
次に、DLLから関数を呼び出して、プラグインをアンロードし、ロードされたすべてのオブジェクトを削除する必要があります。
bool IFloorSystem::UnRegisterEffectPlugin(IFloorEffectPluginBase * plugin)
{
IFloorEffectPluginBaseList::compatibility_iterator it = m_Plugins.Find(plugin);
if (it == NULL)
return false;
do
{
wxDynamicLibrary * dll = m_MapPluginsDll[plugin];
if (!dll) // Probably plugin was not loaded from dll
break;
wxDYNLIB_FUNCTION(DeletePlugin_function, DeletePlugin, *dll);
if (pfnDeletePlugin)
{
pfnDeletePlugin(plugin);
m_Plugins.Erase(it);
m_MapPluginsDll.erase(plugin);
return true;
}
} while (false);
// If plugin is not loaded from DLL
wxDELETE(plugin);
m_Plugins.Erase(it);
return true;
}