2
\$\begingroup\$

Background: I'm writing C++ code after a fairly long time, so I may not be up to date on the best practices, so please bear with me. I'm only trying to improve and learn.

Problem I need to write a wrapper in C++/CLI for a C++ library so that I can use it in C#. The limitation that C++/CLI managed types can only contain pointers to native types is very frustrating. Part of the reason is that the native library I'm wrapping around has classes that are often passed around among themselves as shared_ptr or native references to instances.

Code My code is inspired by this post but I'm trying to use shared_ptrs instead of the raw pointers.

#pragma once
#include <memory>

namespace App
{
    using namespace System;

    template<typename T>
    public ref class Managed
    {
    private:
        std::shared_ptr<T>* native;

    protected:
        !Managed()
        {
            delete native;
        }

    private protected:
        // Allows derived classes to construct native objects with parameters
        // but only accepts shared_ptr
        Managed(std::shared_ptr<T> t) : native(new std::shared_ptr<T>(t)) {}

        // Assumes default constructor for the native object
        Managed() : Managed(std::make_shared<T>()) {}

    internal:

        /*
        Return a reference to the native object
        */
        [CLSCompliantAttribute(false)]
        property T& WrappedObject
        {
            T& get()
            {
                return **native;
            }
        }

        /*
        Return a shared pointer by value to the native object
        */
        [CLSCompliantAttribute(false)]
        property std::shared_ptr<T> WrappedPointer
        {
            std::shared_ptr<T> get()
            {
                return *native;
            }
        }

    public:
        virtual ~Managed()
        {
            this->!Managed();
        }
    };
}

The wrapper can be used like so (this is just an example, not something I'm actually using):

public ref class NativeObjWrapper: Managed<NativeObj>
{
public:
        NativeObjWrapper(int x) : Managed<NativeObj>(std::make_shared<NativeObj>(x)) {}

        NativeObjWrapper() {}

        // Example for passing by reference
        void SetPropertyByReference(AnotherNativeObjWrapper^ another)
        {
            WrappedObject.setProperty(another.WrappedObject);
        }
}

If somebody could take a look and point some obvious flaws that I'm overlooking, that'd be great.

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Browse other questions tagged or ask your own question.