tbb::flow::graph 的功能对象中的嵌套对象问题
Problems with nested object in functional object of the tbb::flow::graph
我有一个功能对象用作 multifunction_node 的正文:
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) 如何正确保持嵌套对象的指针?
更新 添加了一些伪代码来防止第一次破坏 dllObject,例如:
bool b = false;
module::~module()
{
if (valid && b)
{
DestroyObject(dllObject);
}
if (!b)
b = true;
valid = false;
}
现在它按预期工作但看起来很丑:/
最大,
我假设您的 typedef
为 multi_node
,这与参考手册示例中的相似。
multifunction_node
的构造函数具有以下签名:
multifunction_node( graph &g, size_t concurrency, Body body );
body 对象在参数传递期间和节点构造期间被复制,因此 mod
在构造期间创建了两个副本(实际上是三个,因为 body 的初始副本也是存储用于在使用 rf_reset_bodies
调用 reset()
时重新初始化正文)。您看到的析构函数调用可能是用于销毁副本的调用。
body 对象还应该定义一个复制构造函数,或者能够接受默认复制构造函数来制作 body 的副本。我认为 QString
定义了一个复制构造函数,但我不知道像 tDataDescription
这样的字段。 (我以为我们已经在参考手册中涵盖了 Body 对象的基本要求,但我仍在寻找该部分。)无论如何,Body class 必须是 CopyConstructible,因为它被复制了多次。
此致,
克里斯
我有一个功能对象用作 multifunction_node 的正文:
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) 如何正确保持嵌套对象的指针?
更新 添加了一些伪代码来防止第一次破坏 dllObject,例如:
bool b = false;
module::~module()
{
if (valid && b)
{
DestroyObject(dllObject);
}
if (!b)
b = true;
valid = false;
}
现在它按预期工作但看起来很丑:/
最大,
我假设您的 typedef
为 multi_node
,这与参考手册示例中的相似。
multifunction_node
的构造函数具有以下签名:
multifunction_node( graph &g, size_t concurrency, Body body );
body 对象在参数传递期间和节点构造期间被复制,因此 mod
在构造期间创建了两个副本(实际上是三个,因为 body 的初始副本也是存储用于在使用 rf_reset_bodies
调用 reset()
时重新初始化正文)。您看到的析构函数调用可能是用于销毁副本的调用。
body 对象还应该定义一个复制构造函数,或者能够接受默认复制构造函数来制作 body 的副本。我认为 QString
定义了一个复制构造函数,但我不知道像 tDataDescription
这样的字段。 (我以为我们已经在参考手册中涵盖了 Body 对象的基本要求,但我仍在寻找该部分。)无论如何,Body class 必须是 CopyConstructible,因为它被复制了多次。
此致, 克里斯