2011-10-16 40 views
4

我在读“Using shared_ptr in dll-interfaces”。在那篇文章中,phlipsy提出了一种方法,在他的答案结束时,不跨DLL边界传递实现特定对象。基本上,这个想法是从DLL返回一个原始指针,并在原始指针中初始化EXE中的shared_ptr正确使用shared_ptr消除DLL边界上的重新分配

我不认为这是正确的。让我为简单重新排版。

// wrong version?? 
// DLL 
Object* createObject() 
{ 
    return new Object; 
} 

// EXE 
std::tr1::shared_ptr<Object> p(createObject()); 
.. 

object被释放,通过使用shared_ptr破坏上下文/堆是从施工过程中DLL使用的不同。

使用shared_ptr的正确方法是资源分配应与shared_ptr初始化在同一行中,以便分配和释放可以使用相同的堆,如下所示。

// right version 
// DLL 
std::tr1::shared_ptr<Object> createObject() 
{ 
    return std::tr1::shared_ptr<Object>(new Object); 
} 

// EXE 
std::tr1::shared_ptr<Object> p(createObject()); 
.. 

对吗?

+1

你是对的。手指交叉,两个模块使用相同的CRT版本。 –

+1

在链接的答案中,他清楚地指出,当这样做时,您将自定义释放函数绑定到'shared_ptr'。 –

+0

@丹尼斯,就是这一点。) –

回答

6

你说的都对。第二种正确的方法是通过createObject(..)返回一个原始指针,用它初始化一个shared_ptr并将一个定制的删除器传递给shared_ptr。自定义删除器是一个类似releaseObject(..)的库函数。

编辑: 随着你的版本(的CreateObject(..)返回一个shared_ptr < ..>)你绑定到特定的shared_ptr实现图书馆和图书馆用户。在我提出的方式中,这个限制消失了。

1

一般规则是分配/释放内存应始终从同一模块完成。因此,您可以使用分配器创建共享指针,该分配器在分配模块中调用正确的释放方法。

适用于原始指针的规则仍然适用,即使您已将它们包装在智能指针中。