Roman Khvostikov
Roman Khvostikov

Reputation: 355

c++/cli wrapper for variable of native smart-pointer class

I'm new to C# and C++/CLI and not quite familiar with them. I searched but couldn't find an existing solution for a pretty simple thing (which I suppose should be common).

I am writing a simple C++/CLI project (a wrapper to C++ native dlls to be used in C#). There are many examples how to write a wrapper for native class:

class CNativeClass { 
    CNativeClass() {}
    void Foo() {}
}

public ref class CNativeClassWrapper {
public:
    CNativeClassWrapper() {
        _Wrapper = new CNativeClass;
    }
    ~CNativeClassWrapper() {
        this->!CNativeClassWrapper();
    }
    !CNativeClassWrapper() {
        delete _Wrapper;
        _Wrapper = nullptr;            
    }
    void Foo() {
        _Wrapper->Foo();
    }
private:
    CNativeClass* _Wrapper;
}

This is simlified example code. There may be more native classes, there may be late initialization... A lot minor but necessary code.

Is there any wrapper for variable of native class which hides all these details? Like smart pointer templates in pure C++.

Moreover, if a native class is actually a smart pointer (90% of my cases, we use boost::shared_ptr<>) the code becomes a mess:

Does anybody know a solution for this?

Upvotes: 3

Views: 2946

Answers (2)

Roman Khvostikov
Roman Khvostikov

Reputation: 355

Well, I have finally come to such wrapper classes:

  • for holding general native classes:

    template <class T>
    public ref class native_auto_ptr
    {
    public:
        native_auto_ptr()
        {
            _pNative = new T;
        }
        native_auto_ptr(const native_auto_ptr<T>% rhs)
        {
            _pNative = new T( *rhs._pNative );
        }
        ~native_auto_ptr()
        {
            reset();
        }
        void reset()
        {
            delete _pNative;
            _pNative = nullptr;
        }
        T* ptr()
        {
            return _pNative;
        }
        T* operator->()
        {
            return _pNative;
        }
        operator bool()
        {
            return _pNative;
        }
        void operator=(const native_auto_ptr<T>% rhs)
        {
            *_pNative = *rhs._pNative;
        }
        void operator=(const T% rhs)
        {
            *_pNative = rhs;
        }
    protected:
        !native_auto_ptr()
        {
            reset();
        }
    private:
        T* _pNative;
    };
    
  • for holding shared_ptr<>:

    template <class T>
    public ref class native_shared_ptr
    {
    public:
        native_shared_ptr()
        {
            _spNative = new boost::shared_ptr<T>;
        }
        native_shared_ptr(const native_shared_ptr<T>% rhs)
        {
            _spNative = new boost::shared_ptr<T>;
            *this = rhs;
        }
        native_shared_ptr(const boost::shared_ptr<T>% rhs)
        {
            _spNative = new boost::shared_ptr<T>( rhs );
        }
        ~native_shared_ptr()
        {
            reset();
        }
        void reset()
        {
            delete _spNative;
            _spNative = nullptr;
        }
        T* operator->()
        {
            return _spNative->get();
        }
        operator bool()
        {
            return _spNative && *_spNative;
        }
        void operator=(const native_shared_ptr<T>% rhs)
        {
            *_spNative = *rhs._spNative;
        }
        void operator=(const boost::shared_ptr<T>% rhs)
        {
            *_spNative = rhs;
        }
    protected:
        !native_shared_ptr()
        {
            reset();
        }
    private:
        boost::shared_ptr<T>* _spNative;
    };
    

I am quite happy :)

  • They hide new/delete jobs.
  • They are safe.
  • Their syntax is close to common smart-pointer, which is convenient.

The only issue is with the ctors with parameters... (TBD)

Upvotes: 2

Sebacote
Sebacote

Reputation: 699

I don't think there is a build-in class shipped with the C++/CLI framework, but you can easily design your own.

Take a look at this question: auto_ptr or shared_ptr equivalent in managed C++/CLI classes

I would not use smart pointers. The managed wrapper to the native object will take care of releasing the native object when the containing managed class is disposed or finalized.

Upvotes: 0

Related Questions