C++/CLI 包装返回 std::shared_ptr 的函数
我目前正在使用 C++/CLI 包装 C++ 类,以实现 .NET 互操作性,遵循在托管类中保存本机指针的标准流程。在一个实例中,我有一个本机类,其功能如下:
std::shared_ptr<BaseChannel> channelData(const int RunNumber);
我已经开始为 BaseChannel
创建一个包装类。但是,如果我将原始指针传递给托管类的构造函数,则无法保证托管类所指向的对象的生命周期。即,shared_ptr 可能超出范围,对象将被删除,托管类将保留一个悬空指针。
对于这种情况,常见的解决方案是什么?
更新
@Ben:所以我像这样包装了保存上述问题中方法的类(假设它位于一个名为 Node
的本机类中,并且它被包装在一个名为 NodeRef 的托管类:
ChannelUser^ NodeRef::ChannelData(int runNumber)
{
// mpNode is native class pointer of type Node held in managed class
// wrapper called NodeRef
std::shared_ptr<BaseChannel> spBaseChannel = mpNode->channelData(runNumber);
// ChannelUser is using clr_scoped_ptr to hold the shared_ptr
ChannelUser^ channelUser = gcnew ChannelUser(spBaseChannel);
return channelUser;
}
因为当通过引用传递给托管类时,shared_ptr 的引用计数没有增加,这是否意味着
只要这个shared_ptr在 范围,它指向的对象将 仍然存在,因为它的参考 计数至少为 1
I'm currently wrapping a C++ class with C++/CLI for .NET interoperability following the standard process of holding a native pointer in a managed class. In one instance, I have a native class that has a function like:
std::shared_ptr<BaseChannel> channelData(const int RunNumber);
I have already begun creating a wrapper class for BaseChannel
. However, if I pass the raw pointer to the constructor of the managed class, there are no guarantees on the lifetime of the object being pointed to by the managed class. I.e. the shared_ptr could go out of scope and the object will get deleted and the managed class will be left holding a dangling pointer.
What is the common solution for this situation?
UPDATE
@Ben: So I wrap the class that holds the method in the above question like so (let's say it is in a native class called Node
and it is being wrapped in a managed class called NodeRef:
ChannelUser^ NodeRef::ChannelData(int runNumber)
{
// mpNode is native class pointer of type Node held in managed class
// wrapper called NodeRef
std::shared_ptr<BaseChannel> spBaseChannel = mpNode->channelData(runNumber);
// ChannelUser is using clr_scoped_ptr to hold the shared_ptr
ChannelUser^ channelUser = gcnew ChannelUser(spBaseChannel);
return channelUser;
}
Because the shared_ptr does not have its reference count increased as it is passed to the managed class by reference, does that mean
that as long as this shared_ptr is in
scope, the object it points to will
still exist, because its reference
count will be at least 1
? (ref C++ - passing references to std::shared_ptr or boost::shared_ptr)
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
这是一个托管的
shared_ptr
。您可以直接从shared_ptr
分配给它,它会获取一个副本,当托管对象被 GC 或处置时,它将删除该副本。示例:
代码:
Here's a managed
shared_ptr<T>
. You can assign to it directly from ashared_ptr
and it'll take a copy that it will delete when the managed object is GC'd or disposed.Examples:
Code:
shared_ptr
是本机类型,托管对象不能具有完整的本机子对象。但是,正如您所注意到的,托管对象可以具有指向本机对象的指针。您需要的是一个指向
shared_ptr
的指针,它将被视为对BaseChannel
对象的引用,并防止其过早释放。当然,使用智能指针而不是原始
shared_ptr*
的原因有很多。我写了一个应该合适的智能指针,你可以在 codereview.stackexchange.com 上找到它: “C++/CLI 的scoped_ptr(确保托管对象正确释放拥有的本机对象)”示例(未编译已测试):
这会自动实现
IDisposable
并在Dispose
或终结器运行时删除shared_ptr
,从而减少shared_ptr
上的引用计数>基本频道。shared_ptr
is a native type, and managed objects can't have integral native subobjects.However, as you note, managed objects can have pointers to native objects. What you need is a pointer to a
shared_ptr
, which will count as a reference to theBaseChannel
object and keep it from being freed prematurely.Of course, there are lots of reasons to use a smart pointer instead of a raw
shared_ptr<BaseChannel>*
. I've written a smart pointer which should be suitable, you can find it on codereview.stackexchange.com: "scoped_ptr for C++/CLI (ensure managed object properly frees owned native object)"Example (not compile tested):
This automatically implements
IDisposable
and deletes theshared_ptr
whenDispose
or the finalizer runs, which in turn reduces the reference count on theBaseChannel
.