c++ - 返回对类静态数据成员的引用的正确方法是什么? (我正在使用 Qt,以防它有所作为)

标签 c++ windows qt winapi dll

我正在尝试从 DLL 中获取类静态数据成员的地址,并将其保存在主机代码中。但是,当我退出 dll-manager 中的方法时,我丢失了对成员的指针/引用,该方法打开了所有 (Windows typedef) HINSTANCE s,即使我让它们保持打开状态.

我的设置是:

一个 Qt GUI 应用程序,其中包含一个从 dll 加载插件的类。这个 dll-manager 类不使用 Qt 的东西,而是到处使用 Qdir 和 Qstrings...

dll-manager 应该发出一堆 LoadLibrary() 调用来打开 DLL,并为每个调用一个导出函数,该函数返回 DLL 导出类中静态“信息”结构的地址。

例如,DLL 类如下所示:

BlackNWhite.h

#ifdef BLACKNWHITE_EXPORTS
#define BLACKNWHITE_API __declspec(dllexport)
#else
#define BLACKNWHITE_API __declspec(dllimport)
#endif

// This class is exported from the BlackNWhite.dll
class BLACKNWHITE_API CBlackNWhite : PCOperatorBase 
{
public:

    CBlackNWhite(void);
    virtual ~CBlackNWhite(void);

    virtual int process(int* inBuffer, int* outBuffer, int bufferSize);
    void getParametersInfo(const std::vector<ParameterDescriptor>*& outParameters);

    static const OperatorInfo& info();

protected:

    static OperatorInfo operatorInfo;
};


 extern "C" __declspec(dllexport) PCOperatorBase* getOperatorInstance();
 extern "C" __declspec(dllexport) const PCOperatorBase::OperatorInfo& getOperatorInfo();

BlackNWhite.cpp

#include "stdafx.h"
#include "BlackNWhite.h"

PCOperatorBase::OperatorInfo CBlackNWhite::operatorInfo = {L"Black N White", L"modifier", L"color"};


const PCOperatorBase::OperatorInfo& CBlackNWhite::info()
{
    return CBlackNWhite::operatorInfo;
}

extern "C" __declspec(dllexport) PCOperatorBase* getOperatorInstance()
{
    return (PCOperatorBase*)(new CBlackNWhite());
}

extern "C"  __declspec(dllexport) const PCOperatorBase::OperatorInfo& getOperatorInfo()
{
    return CBlackNWhite::info();
}

CBlackNWhite::CBlackNWhite()
    : PCOperatorBase()
{
    ParameterDescriptor newParameter;
    newParameter.label = L"Parameter 1";
    parameters.push_back(newParameter);
}

CBlackNWhite::~CBlackNWhite()
{
}

int CBlackNWhite::process(int* inBuffer, int* outBuffer, int bufferSize)
{
    while(bufferSize--)
        *outBuffer++ = *inBuffer++;

    return 0;
}

void CBlackNWhite::getParametersInfo(const std::vector<ParameterDescriptor>*& outParameters)
{
    outParameters = &parameters;
}

并且这个类继承自一个基类:

PCOperatorBase.h

#pragma once

#include "PCOperatorParameters.h"
#include <vector>

class PCOperatorBase
{
public:

    typedef struct OperatorInfo
    {
        wchar_t* name;
        wchar_t* type;
        wchar_t* subtype;

    } OperatorInfo;

    PCOperatorBase(void){};
    virtual ~PCOperatorBase(void){};

    virtual void getParametersInfo(const std::vector<ParameterDescriptor>*& outParameters) = 0;
    virtual int process(int* inBuffer, int* outBuffer, int bufferSize) = 0;

protected:

    std::vector<ParameterDescriptor>parameters;
};

DLL 管理器有两个相关方法。一个构建可用插件列表,另一个只返回插件的字符串名称。

void PCOperatorManager::buildOperatorList(const QString path)
{
    QDir operatorDirectory(QDir::currentPath() + path);

    if(operatorList.size())
        operatorList.clear();

    QStringList operatorNameList = operatorDirectory.entryList(QStringList("*.dll"));

    typedef PCOperatorBase::OperatorInfo*(*PCOClassInfoFunction)();

    for(QStringList::iterator PCOClassName = operatorNameList.begin();
        PCOClassName != operatorNameList.end();
        PCOClassName++)
    {
        HINSTANCE PCOClassHandle;
        if((PCOClassHandle = LoadLibrary((operatorDirectory.absolutePath() + "/"+ *PCOClassName).toStdWString().c_str())))
        {
            OperatorDescriptor newPCOClassDescriptor;
            newPCOClassDescriptor.handle = PCOClassHandle;
            newPCOClassDescriptor.info = (*((PCOClassInfoFunction)GetProcAddress(PCOClassHandle, "getOperatorInfo")))();
            operatorList.push_back(newPCOClassDescriptor);

            printf("\n we have: %ls", operatorList[0].info->name);

        }
    }
}

QStringList PCOperatorManager::getOperatorNameList()
{
    QStringList operatorNameList;

    printf("\n the list length is: %i", operatorList.size());
    for(int i = 0; i < operatorList.size(); i++)
        printf("\n we have again: %ls", operatorList[0].info->name);

//operatorNameList << QString::fromWCharArray((*PCOClass).info.name);


    return operatorNameList;
}

发生的事情是:在 buildOperatorList() 内部,我可以访问 DLL 类的静态成员并将其分配给 OperatorDescriptor 结构中的信息成员。也就是说,读取“我们有”的“测试”printf 语句确实打印出该字段的正确值。

但是,在 getOperatorNameList() 中,信息成员不再有效。

我的想法是,我正在做的是:

  1. 我有一个指向 OperatorInfo 结构的指针,称为信息。
  2. 我得到了 DLL 类中静态 OperatorInfo 结构的地址, 称为 operatorInfo。
  3. 我将类的 operatorInfo 的地址分配给指针 称为信息。即 info = &CBlackNWhite::operatorInfo;

此时,只要我不在 DLL HINSTANCE

上发出 FreeLibrary(),指针就应该保持有效

这是怎么回事?

最佳答案

我在这里看到 operatorList 不是 PCOperatorManager 的成员变量,一旦它像 buildOperatorList 一样被添加和构造,我想你应该有访问权限在 getOperatorNameList()

关于c++ - 返回对类静态数据成员的引用的正确方法是什么? (我正在使用 Qt,以防它有所作为),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10100131/

相关文章:

c++ - 如何使用 SendMessage 函数发送用户数据?

windows - 删除指向文件的链接而不清除只读位

c++ - 如何使用 qt c++ 管理来自本地机器的网络流量

c++ - ceil 函数描述的意外行为

c++ - 二维动态数组C++显示问题

c++ - 如何从另一个 C++ 控制台应用程序启动/结束一个 C++ 控制台应用程序?

windows - 如何在作为 Windows 服务运行的 tomcat7 上启用 JMX?

c++ - 将动态数组分配作为函数尝试时出现运行时错误

c++ - 在 Qt5 的对象指针上使用 qRegisterMetaType 会引发 Unresolved 错误

c++ - Qt 程序在另一台计算机上执行时崩溃