0
votes

I have a managed class that has a member that is a pointer to native object. Like this (not a real code):

ref class ManagedClass {

private:
    NativeClass* ptr = nullptr;

};

I need to initialize this pointer to point to a valid object by calling a native method, that takes pointer-to-pointer:

void native_init(NativeClass** nc);

But when I try to get this pointer-to-pointer for ptr by:

native_init(&ptr);

VS shows a message that

argument of type interion_ptr is incompatible with parameter of type NativeClass**

So, how can I get pointer to that pointer?

This code works:

NativeClass *local_ptr;
native_init(&local_ptr);
ptr = local_ptr;

But when I try to delete it like this:

delete ptr

The application crashes saying that I try to "to read or write protected memory". What should I do?

1

1 Answers

3
votes

Well, a managed object can be moved around in memory, which is the reason why the compiler doesn't let you take an address to it - that address will become outdated sooner or later.

You can take an address to a managed reference type object after pinning it. The simplest would be to use pin_ptr, the object will be guaranteed not to move in memory until the pin_ptr goes out of scope.

So you can write this:

auto managedObject = gcnew ManagedClass();
pin_ptr<NativeClass*> pinnedNativePtr = &managedObject->ptr;
native_init(pinnedNativePtr);

But make sure the NativeClass** won't be kept around and accessed after the call to native_init.


As to your attempt, it's certainly valid. But you're getting an AccessViolationException most probably because native_init didn't use the new operator to create the object, or used a different runtime. If you're trying to use a library, it should provide some sort of native_free function, so use that instead of delete.