首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >wxWidgets -通过DLL向sizer添加项

wxWidgets -通过DLL向sizer添加项
EN

Stack Overflow用户
提问于 2012-12-02 23:00:30
回答 1查看 496关注 0票数 1

我有一个用wxWidgets (C++,MSVC)建立的图形用户界面,其部分功能是通过DLL将元素添加到GUI中。本质上,我将向DLL传递一个sizer,后者将根据DLL中的元素添加元素。

有人能指点我如何设置DLL吗?我已经看过了,但没有看到任何与我正在寻找的东西类似的东西。元素的编程很好,我只需要了解如何构造DLL编程。

帮助感激。

更新

我做了一些类似于Plugins的事情。

本质上,每当我尝试在DLL中使用wxWidgets组件时,都会出现访问冲突读取位置错误。

在samplePlugin.cpp中,如果使用

代码语言:javascript
复制
void samplePlugin::PerformTasks()
{
   wxMessageBox(_("I would if I could..."));
}

我明白错误了。但是,如果我用

代码语言:javascript
复制
void samplePlugin::PerformTasks()
{
   MessageBox(0,"Testing this thing","Test",0);
}

它不是wxWidgets,而是操作系统的本机,消息框工作正常。

我尝试在DLL和App项目中添加WXUSINGDLL;WXMAKINGDLL;MSVC的预处理定义中的WXUSINGDLL;DLL编译得很好,但在这种情况下,我甚至不能编译应用程序并得到异常。

有人知道如何解决这个问题吗?

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2012-12-02 23:25:16

创建DLL项目并指定预处理指令,例如/DIFLOOR_EXPORTS_COMMONPLUGINBASE (此预处理器变量仅在DLL项目中)

然后创建一个标头,指定您的类是导入还是导出:

CommonPluing.h

代码语言:javascript
复制
#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

代码语言:javascript
复制
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 *父)方法:

Exports.cpp

代码语言:javascript
复制
#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

代码语言:javascript
复制
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调用函数来卸载插件和删除所有加载的对象:

代码语言:javascript
复制
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;
}
票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/13674887

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档