VC++/CLI: How to prevent an unmanaged object from being destroyed when it goes out of scope?

183 views Asked by At

I have a third-party unmanaged C++ library which has two classes, let's call them ClassA and ClassB. ClassA has a method, let's call it getTheB(), which returns an instance of ClassB - it does not return a pointer to the instance, but the instance itself.

I now wrote a managed wrapper for ClassA which in turn has a method getTheB() which returns a managed wrapper wrapping the ClassB.

The original ClassB object from the third-party library has to be handed over to my managed wrapper via its pointer, like:

ThirdParty::ClassB db = delegateForClassA -> getTheB();
ManagedClassB^ mb = gcnew ManagedClassB(&db);

However, when my wrapped getTheB() of my ClassA wrapper finishes and the scope ends, the ManagedClassB instance contains a dangling reference to the third-party ClassB and the destructor of the latter one is called, leading to funny results when accessing methods of ClassB.

In my other question, I was told to somehow store the original ClassB object, but I don't know how.

So, how do I keep the third-party ClassB instance alive?

2

There are 2 answers

5
KABoissonneault On BEST ANSWER

You can either change getTheB to return a heap-allocated ClassB, or have ManagedClassB make his own copy of the db object.

Update for the copy:

I assume ManagedClassB's constructor looks something like

public ref class ManagedClassB
{
public:
    ManagedClassB(ClassB* p)
        : m_p(p) { }
...
private:
    ClassB* m_p;
};

You should simply change it to

public ref class ManagedClassB
{
public:
    ManagedClassB(const ClassB& b)
        : m_b(b) { }
...
private:
    ClassB m_b;
};

or

public ref class ManagedClassB
{
public:
    ManagedClassB(ClassB* p)
        : m_p(new ClassB(*p)) { }
...
private:
    ClassB* m_p;
};
5
donjuedo On

You should be allocating the db in the scope appropriate for your use. You know what is best for you, be it a static member of something, or a basic global, or whatever. The scope must remain valid as long as you need db, and execution can go out of scope when you're done with it.