Search code examples
.netc++-clismart-pointersmixed-mode

Ampersand Operator in Mixed Managed/Unmanaged C++/CLI Project


In writing a function within a C++/CLI ref class, I wish to pass a pointer to a pointer to an object when calling a native function.

Native Function

void MyNativeFunc(NativeObject** obj);

Managed C++/CLI Function

ref class ManagedType
{
    static NativeObject* m_NativeObj;
    void MyManagedFunc()
    {
        MyNativeFunc(&m_NativeObj);  // Error here
    }
}

The problem here is that &m_NativeObj in C++/CLI is not a NativeObject**. It is an interior_ptr<NativeObject*> which the native function cannot accept. Is there an syntax such that I can perform this simple reference operation without incurring the managed pointer?

Edit: Apologies. Initially, the m_NativeObj was a function member in the question, not a static member of the class. I have the problem only if it is a static member.


Solution

  • I assume the reason your native function is taking a NativeObject** is because the function will assign a new object to it, in which case you can do something like this:

    class NativeObject { };
    
    void MyNativeFunc(NativeObject** obj) {
        *obj = new NativeObject;
    }
    
    ref class ManagedObject
    {
    public:
        void Test()
        {
            NativeObject* p = nullptr;
            MyNativeFunc(&p);
            delete m_NativeObj;
            m_NativeObj = p;
        }
    
        static NativeObject* m_NativeObj = nullptr;
    };
    

    On the other hand, if the native function is an in/out function that may assign a new value to the pointer, you can code something like this:

    class NativeObject { };
    
    void MyNativeFunc(NativeObject** obj) {
        if (!(*obj))
            *obj = new NativeObject;
    }
    
    ref class ManagedObject
    {
    public:
        void Test()
        {
            pin_ptr<NativeObject> pinned = m_NativeObj;
            NativeObject* p = pinned;
            MyNativeFunc(&p);
            if (p != m_NativeObj)
            {
                delete m_NativeObj;
                m_NativeObj = p;
            }
        }
    
        static NativeObject* m_NativeObj = nullptr;
    };