Search code examples
pointersc++-clipin-ptr

issues with interior_ptr pin_ptr


I'm trying to construct a cli/c++ ref class. The purpose of this class is to wrap a native class pointer with some functionality. The native class pointer gets provided to me by a black box factory method. For the life of me I cant figure out how to pin the native pointer so it does not move. Here is the scenario in code(so to speak):

public ref class ManagedFoo{
    private: 
        NativeFooClass* myFoo;
    public:
        ManagedFoo(){
            NativeFooFactory factory();
            NativeFooClass* nativePtr = factory.CreateFoo();
            //here is where i get lost 
            //create a pined pointer to the nativePtr
            pin_ptr<NativeFooClass*> pinPtr = &nativePtr;
            //tring to assign pinPtr to the mamaber var= compilation faliuer 
            myFoo = pinPtr;
        }
}

I keep getting: error C2440: '=' : cannot convert from 'cli::pin_ptr' to 'NativeFooClass*'

I thought the compiler treats them the same? Do i need to static cast? That does not seem right???

The reason I'm trying to pin this pointer is because when I try to use it in a method, and then call this method from C# i get an AccessViolation runtime error "{"Attempted to read or write protected memory. This is often an indication that other memory is corrupt."}"


Solution

  • You don't need to. Native objects are stored in memory which is not managed by the .NET garbage collector -- they won't be moved around, and pinning would have no effect.

    Simply

        ManagedFoo()
        {
            NativeFooFactory factory; // fixed most-vexing parse
            myFoo = factory.CreateFoo();
        }
    

    should be sufficient.

    Or even better

        ManagedFoo()
            : myFoo{NativeFooFactory().CreateFoo()}
        {
        }
    

    UPDATE: Since we find out the object can't outlive its factory,

        ManagedFoo()
            : myFooFactory{new NativeFooFactory()}
            , myFoo{myFooFactory->CreateFoo()}
        {
        }
    

    Although I would suggest some sort of smart pointer to make sure the native objects are correctly freed, perhaps my clr_scoped_ptr.