tbb::flow::图的函数对象中嵌套对象的问题

Problems with nested object in functional object of the tbb::flow::graph

本文关键字:对象 嵌套 问题 flow tbb 函数      更新时间:2023-10-16

我有一个函数对象,我正在使用它作为多功能节点的主体:

class module
{
private:
    bool valid;
    QString description;
    bool hasDetectionBranch;
    tDataDescription bufData;
    void* dllObject; //<-- This is a pointer to an object constructed with help of the external dll
    qint64 TimeOut;
public:
    module(const QString& _ExtLibName);
    virtual ~module();
    void operator() (pTransmitData _transmitData, multi_node::output_ports_type &op);
};

"dllObject"是在对象"module"的构造时创建的:

module::module(const QString& _ExtLibName) :
    valid(true), hasDetectionBranch(false)
{
    GetObjectDescription = (tGetObjectDescription)QLibrary::resolve(_ExtLibName, "GetObjectDescription");
    CreateObject = (tCreateObject)QLibrary::resolve(_ExtLibName, "CreateObject");
    DestroyObject = (tDestroyObject)QLibrary::resolve(_ExtLibName, "DestroyObject");
    if (!CreateObject || !DestroyObject || !GetObjectDescription)
        valid = false;
    else
    {
        description = QString(GetObjectDescription());
        dllObject = CreateObject();
    }
}

这是当"dllObject"被销毁时:

module::~module()
{
    if (valid)
    {
        DestroyObject(dllObject);
    }
}

我建立了一个小图表:

void MainWindow::goBabyClicked(void)
{
    module mod(QString("my.dll")); //<-- Here is OK and mod.dllObject is correct
    if (!mod.isValid())
    {
        qDebug() << "mod is invalid!n";
        return;
    }
    first fir(input);
    folder fol(QString("C:/out"), 10000);
    graph g;
    source_node<pTransmitData> src(g, fir, false);
    multi_node mnode(g, tbb::flow::serial, mod); //<-- WTF? ~module() is executed!
    function_node<pTransmitData> f(g, tbb::flow::serial, fol);
    make_edge(src, mnode);
    make_edge(mnode, f);
    src.activate();
    g.wait_for_all();
}

所以我有两个问题:1) 为什么要执行~module(),以及如何防止这种情况发生?2) 如何正确地保持嵌套对象的指针?

UPDATE添加了一些伪代码以防止第一次破坏dllObject,如:

bool b = false;
module::~module()
{
    if (valid && b)
    {
        DestroyObject(dllObject);
    }
    if (!b)
        b = true;
    valid = false;
}

现在它按预期工作,但看起来很难看:/

最大

我假设您有一个multi_nodetypedef,它与参考手册示例中的类似。

multifunction_node的构造函数具有以下签名:

multifunction_node( graph &g, size_t concurrency, Body body );

body对象在参数传递过程中以及在节点构造过程中都会被复制,因此在构造过程中创建了两个mod副本(实际上是三个,因为在用rf_reset_bodies调用reset()时,还存储了一个body的初始副本,用于重新初始化body)。您看到的析构函数调用可能是用于销毁副本的调用。

body对象还应该定义一个复制构造函数,或者能够接受默认的复制构造函数来复制body。我认为QString定义了一个复制构造函数,但我不知道像tDataDescription这样的字段。(我以为我们已经在参考手册中介绍了Body对象的基本要求,但我仍在寻找该部分。)无论如何,Body类必须是CopyConstructable,因为它被复制了多次。

谨致问候,Chris