我有一个功能对象,我正在使用它作为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)为什么~codule()被执行以及如何防止这种情况? 2)如何正确保存嵌套对象的指针?
UPDATE 添加了一些虚拟代码,以防止在第一时间销毁dllObject,如:
bool b = false;
module::~module()
{
if (valid && b)
{
DestroyObject(dllObject);
}
if (!b)
b = true;
valid = false;
}
现在它按预期工作但看起来很难看:/
答案 0 :(得分:1)
最大,
我假设您的typedef
multi_node
与参考手册示例中的multifunction_node
类似。
multifunction_node( graph &g, size_t concurrency, Body body );
的构造函数具有以下签名:
mod
在参数传递期间以及在构造节点期间复制了body对象,因此在构造期间创建了两个reset()
副本(实际上是三个,因为正文的初始副本也存储为使用rf_reset_bodies
调用QString
时重新初始化正文。析构函数调用你看到的可能就是用来销毁副本的那些。
body对象还应该定义一个copy-constructor,或者能够接受default-copy-constructor来创建body的副本。我认为tDataDescription
定义了一个拷贝构造函数,但我不知道像1,4,3,5
这样的字段。 (我认为我们已经在参考手册中介绍了Body对象的基本要求,但我仍然在寻找该部分。)在任何情况下,Body类必须是CopyConstructible,因为它被复制多次。
此致 克里斯