C ++ / CLI资源管理混乱 [英] C++/CLI Resource Management Confusion

查看:219
本文介绍了C ++ / CLI资源管理混乱的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我对C ++ / CLI中的资源管理非常困惑。我认为我有一个句柄(没有双关语意图),但我偶然发现了 auto_gcroot< T> 类,同时查找头文件,这导致google搜索,那么更好的一天的阅读文档,现在的混乱。所以我想我会转向社区。

I am extremely confused about resource management in C++/CLI. I thought I had a handle (no pun intended) on it, but I stumbled across the auto_gcroot<T> class while looking through header files, which led to a google search, then the better part of day reading documentation, and now confusion. So I figured I'd turn to the community.

我的问题涉及auto_handle / stack语义和auto_gcroot / gcroot之间的区别。

My questions concern the difference between auto_handle/stack semantics, and auto_gcroot/gcroot.


  1. auto_handle:我的理解是,这将清理在托管功能中创建的托管对象。我的困惑是,不是垃圾收集器应该为我们这样做?是不是托管代码的整个点?更具体的:

  1. auto_handle: My understanding is that this will clean up a managed object created in a managed function. My confusion is that isn't the garbage collector supposed to do that for us? Wasn't that the whole point of managed code? To be more specific:

//Everything that follows is managed code
void WillThisLeak(void)
{
    String ^str = gcnew String ^();
    //Did I just leak memory? Or will GC clean this up? what if an exception is thrown?
}

void NotGoingToLeak(void)
{
    String ^str = gcnew String^();
    delete str;
    //Guaranteed not to leak, but is this necessary? 
}

void AlsoNotGoingToLeak(void)
{
    auto_handle<String ^> str = gcnew String^();
    //Also Guaranteed not to leak, but is this necessary? 
}

void DidntEvenKnowICouldDoThisUntilToday(void)
{
    String str();
    //Also Guaranteed not to leak, but is this necessary? 
}

现在这对我来说是有意义的,如果它是C#的替代使用关键字,并且它只推荐用于像Bitmap这样的资源密集型类型,但是这在文档中的任何地方都没有提及,所以这种现在一直在泄漏记忆。

Now this would make sense to me if it was a replacement for the C# using keyword, and it was only recommended for use with resource-intensive types like Bitmap, but this isnt mentioned anywhere in the docs so im afraid ive been leaking memory this whole time now

auto_gcroot

auto_gcroot

我可以将其作为参数传递给本机函数吗?复印会发生什么?

Can I pass it as an argument to a native function? What will happen on copy?

    void function(void)
    {
        auto_gcroot<Bitmap ^> bmp = //load bitmap from somewhere
        manipulateBmp(bmp);
        pictureBox.Image = bmp;  //Is my Bitmap now disposed of by auto_gcroot?
    }

    #pragma unmanaged

    void maipulateBmp(auto_gcroot<Bitmap ^> bmp)
    {
        //Do stuff to bmp
        //destructor for bmp is now called right? does this call dispose?
    }

如果我使用gcroot,这会有效吗?

Would this have worked if I'd used a gcroot instead?

此外,拥有auto_handle和auto_gcroot有什么优点?看起来他们做了类似的事情。

Furthermore, what is the advantage to having auto_handle and auto_gcroot? It seems like they do similar things.

我必须误解一些东西,这样没有什么意义,所以一个很好的解释是伟大的。还有关于正确使用这些类型的任何指导,我可以去学习这个东西的地方,以及任何更多的良好做法/地方,我可以找到他们将非常感谢。

I must be misunderstanding something for this to make so little sense, so a good explanation would be great. Also any guidance regarding the proper use of these types, places where I can go to learn this stuff, and any more good practices/places I can find them would be greatly appreciated.

感谢很多,
最大

thanks a lot, Max

推荐答案


  1. 记住在托管对象上调用的 delete 类似于在C#中调用Dispose。所以你是对的,auto_handle让你做你会做什么与<#code>使用语句在C#。它确保 delete 在作用域结束时调用。所以,不,你不泄漏管理内存,如果你不使用auto_handle(垃圾收集器照顾),你只是没有调用Dispose。如果您处理的类型没有实现IDisposable,则不需要使用auto_handle。

  1. Remember delete called on managed object is akin to calling Dispose in C#. So you are right, that auto_handle lets you do what you would do with the using statement in C#. It ensures that delete gets called at the end of the scope. So, no, you're not leaking managed memory if you don't use auto_handle (the garbage collector takes care of that), you are just failing to call Dispose. there is no need for using auto_handle if the types your dealing with do not implement IDisposable.

gcroot用于保持托管类型一个本地类。您不能使用帽子 ^ 符号直接在本机类型中声明Manged类型。你必须使用gcroot。这是一个垃圾回收根。所以,虽然gcroot(一个本地对象)生活,垃圾回收器不能收集这个对象。当gcroot被销毁时,它允许引用,并且垃圾收集器可以自由收集对象(假设它没有其他引用)。你在类似上面的方法中声明一个独立的gcroot - 只要使用帽子 ^ 语法。

gcroot is used when you want to hold on to a managed type inside a native class. You can't just declare a manged type directly in a native type using the hat ^ symbol. You must use a gcroot. This is a "garbage collected root". So, while the gcroot (a native object) lives, the garbage collector cannot collect this object. When the gcroot is destroyed, it lets go of the reference, and the garbage collector is free to collect the object (assuming it has no other references). You declare a free-standing gcroot in a method like you've done above--just use the hat ^ syntax whenever you can.

那么什么时候使用auto_gcroot?当你需要在本地类中持有一个Manged类型并且该托管类型恰好实现IDisposable时,将使用它。在销毁auto_gcroot时,它将做两件事情:在托管类型上调用delete(认为这是一个Dispose调用 - 没有内存被释放),并释放引用(所以类型可以被垃圾收集)。

So when would you use auto_gcroot? It would be used when you need to hold on to a manged type inside a native class AND that managed type happens to implement IDisposable. On destruction of the auto_gcroot, it will do 2 things: call delete on the managed type (think of this as a Dispose call--no memory is freed) and free the reference (so the type can be garbage collected).

希望它有帮助!

一些参考资料:

http://msdn.microsoft.com/en-us/library /aa730837(v=vs.80).aspx

http://msdn.microsoft.com/en-us/library/481fa11f(v=vs.80).aspx

http://www.codeproject。 com / Articles / 14520 / C-CLI-Library-classes-for-interop-scenarios

这篇关于C ++ / CLI资源管理混乱的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆