This is a continuation of my previous question here. A little introduction:
"I am developing a library which has two layers, unmanaged (C++) and managed (C++/CLI). The unmanaged layer contains the logics and the computation algorithms, while the managed layer provides interface and visualisation to a .NET-based host application. A class in the managed layer wraps its class counterpart in the unmanaged layer, e.g. ManagedA wraps UnmanagedA and ManagedB wraps UnmanagedB."
For clarity, these two layers are implemented as separate DLLs.
In the previous post I asked about wrapping the same unmanaged object in multiple managed objects, which can be done using std::shared_ptr. However, the solution that I wrote (snippet below), based on a reply to the original question, has a constructor with a shared_ptr argument, which assumes that the C++ DLL passes an std::shared_ptr instance.
My question is: is it recommended to pass a std::shared_ptr across different DLLs? A commentator here does not recommend doing so because of potential compatibility issues. However this was written in 2009, so I am wondering if there has been a new argument in favour of doing this.
Edit for elaboration: The next question is, if not recommended, what would be the alternative? The problem is, if UnmanagedA::B() returns a raw pointer, ManagedB will treat it as a new instance which has not been shared yet. Therefore, when one of two ManagedB instances go out of scope, the UnmanagedB instance will be deleted, and this invalidates the pointer inside the other ManagedB instance. Many thanks.
// Unmanaged classes in a C++ DLL
class UnmanagedB
{
public:
UnmanagedB() {}
~UnmanagedB() {}
int i = 0;
};
class UnmanagedA
{
public:
UnmanagedA(UnmanagedB* pUnmanagedB)
: m_pUnmanagedB(pUnmanagedB)
{
}
~UnmanagedA() {}
std::shared_ptr<UnmanagedB> B() { return m_pUnmanagedB; }
protected:
std::shared_ptr<UnmanagedB> m_pUnmanagedB;
};
// Managed classes in a C++/CLI DLL
public ref class ManagedA : IDisposable
{
public:
ManagedA(UnmanagedA* pUnmanagedA)
: m_pUnmanagedA(pUnmanagedA)
{
}
~ManagedA()
{
delete m_pUnmanagedA;
}
ManagedB^ B()
{
return gcnew ManagedB(m_pUnmanagedA->B());
}
private:
UnmanagedA* m_pUnmanagedA;
};
public ref class ManagedB : IDisposable
{
public:
ManagedB(const std::shared_ptr<UnmanagedB>& rkUnmanagedB)
: m_pUnmanagedB(new std::shared_ptr<UnmanagedB>(rkUnmanagedB))
{
}
~ManagedB()
{
delete m_pUnmanagedB;
}
private:
std::shared_ptr<UnmanagedB>* m_pUnmanagedB;
std::shared_ptr<UnmanagedB> GetPtr() { return *m_pUnmanagedB; }
};