简体   繁体   English

使用c ++ / cli interop管理内存

[英]managing memory with c++/cli interop

Most of the code I have seen deletes the pointer in the finalizer/destructor: 我看到的大多数代码都会删除终结器/析构函数中的指针:

public ref class CPPObjectWrapper
{
private:
    CPPObject *_cppObject;
public:
    CPPObjectWrapper()
    {
        _cppObject = new CPPObject();
    }

    CPPObjectWrapper(IntPtr ^ptr)
    {
        _cppObject = ptr->ToPointer();
    }

    ~CPPObjectWrapper()
    {
        delete _cppObject;
        _cppObject = 0;
    }

    !CPPObjectWrapper()
    {
        if (_cppObject != 0) delete _cppObject;
    }

    IntPtr^ GetPointer()
    {
        return gcnew IntPtr(_cppObject);
    }
}

My question is what would be standard practice if the library your wrapping does something like this: 我的问题是,如果包装的库执行以下操作,这将是标准做法:

void AddObject(CPPObject *cppObject)
{
    // adds to a std::list
}

CPPObject* FindObject(/* criteria */)
{
    // return reference to std::list item based on criteria
}

If your c# wrapper does this: 如果您的C#包装器这样做:

void AddObject(CPPObjectWrapper ^cppObject)
{
    _internal->addObject(cppObject->GetPointer()->ToPointer());
}

CPPObjectWrapper^ FindObject(/* criteria */)
{
    CPPObject *cppObject = _internal->findObject(/* criteria */);

    return gcnew CPPObjectWrapper(gcnew IntPtr(cppObjet));
}

You run into a memory issue because your managed object should not delete the pointer because its referenced in another object. 您遇到了内存问题,因为您的托管对象不应删除该指针,因为该指针已在另一个对象中引用。 The same is true when returning. 返回时也是如此。 Would you simply add functionality to tell your managed wrapper not to free the memory when ownership is transferred? 您是否只是添加功能以告诉您的托管包装器在所有权转移时不要释放内存?

A classic situation when dealing with mixed mode projects, and your suggestion is OK! 处理混合模式项目时的经典情况,您的建议还可以!

It would make sense to have a bool in the constructor that tells it not to destroy the pointer if the same object is used in another non-wrapped object. 如果在另一个非包装对象中使用了相同的对象,则在构造函数中使用bool告诉它不要破坏指针是很有意义的。 The ideal case is that every object was wrapped, and the destruction would be done by the CLR. 理想的情况是每个对象都被包装,并且销毁将由CLR完成。

You can make a generic base class out of this (using the code you already have there), setting the bool by default by the subclass. 您可以从中创建通用基类(使用那里已有的代码),默认情况下由子类设置布尔值。 You are guaranteed to have this functionality many times over. 您可以保证多次使用此功能。 Another tip is to have a virtual OnFinalize() method that is called from the CLR destructor (!) that can do special operations in the subclass, like calling some special free function provided by the native library. 另一个技巧是要有一个从CLR析构函数(!)调用的虚拟OnFinalize()方法,该方法可以在子类中执行特殊操作,如调用本机库提供的某些特殊的自由函数。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM