wxWidgets-通过DLL将项目添加到sizer
wxWidgets - Add items to sizer via DLL
我用wxWidgets(C++,MSVC)设置了一个GUI,其中一部分功能是通过DLL向GUI添加元素。从本质上讲,我将向DLL传递一个sizer,它将根据DLL中的内容添加元素。
有人能告诉我如何设置DLL的正确方向吗?我已经看了,但没有看到任何与我要找的相似的东西。元素的编程对我来说很好,我只需要了解如何构造DLL编程。
感谢您的帮助。
更新
我做过类似的事情http://wiki.wxwidgets.org/Programs_That_Support_Plugins.
从本质上讲,每当我尝试从DLL中使用wxWidgets组件时,我都会收到访问冲突读取位置错误。
在samplePlugin.cpp中,如果我使用
void samplePlugin::PerformTasks()
{
wxMessageBox(_("I would if I could..."));
}
我明白错误。但是,如果我使用
void samplePlugin::PerformTasks()
{
MessageBox(0,"Testing this thing","Test",0);
}
它不是wxWidgets,而是操作系统的本地版本,消息框运行良好。
我已经尝试添加WXUSINGDLL;wxmakingll;在DLL和应用程序项目的MSVC中的预处理器定义中。DLL编译得很好,但在这种情况下,我甚至无法编译应用程序并获得异常。
有人知道如何解决这个问题吗?
创建一个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*父)方法:
导出.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;
}
- 将成员变量添加到共享库中的类中,不会破坏二进制兼容性吗
- 如何在C++中从两个单独的for循环中添加两个数组
- POCO::PostgreSQL:如何将std::vector支持添加到`Binder::bind`
- 如何仅为一个函数添加延迟
- 如何防止 c++ 在从浮点型转换为双精度型(不适用于 IO)时添加额外的小数?
- 使用std::transform将一个范围的元素添加到另一个范围中
- 如何将更多文件夹添加到c++include路径
- 如何将元素添加到数组的线程安全函数?
- QT通过C++添加映射QML项目
- 如何将点击的信号和插槽添加到qt中的自定义按钮中
- 如何使用重载的相等(==)运算符向测试用例添加描述
- 为什么Mat类的两个对象可以在不重载运算符+的情况下添加
- 如何防止clang格式在流运算符调用之间添加换行符<<
- 只能向C++添加一定数量的字符
- Qt和C++:将QLineEdit添加到QTabWidget中
- 将QIcon添加到QTableView单元格
- 为什么我必须在C++中添加一个赋值符号来声明一个数组
- 为什么除非添加括号,否则构造函数上的模板替换会失败?
- 将图像添加到资源文件夹UWP C++
- wxWidgets-通过DLL将项目添加到sizer