2016-07-07 2 views
0

У меня есть управляемый класс, который имеет элемент, который является указателем на собственный объект. Как это (не реальный код):Указатель C++ для указателя на собственный объект

ref class ManagedClass { 

private: 
    NativeClass* ptr = nullptr; 

}; 

мне нужно инициализировать этот указатель указывает на допустимый объект, вызвав нативный метод, который принимает указатель на указатель:

void native_init(NativeClass** nc); 

Но когда я пытаюсь получить этот указатель на указатель на PTR по:

native_init(&ptr); 

VS показывает сообщение, что

аргумент типа interion_ptr несовместима с параметром типа NativeClass **

Итак, как я могу получить указатель на этот указатель?

Этот код работает:

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

Но когда я пытаюсь удалить это следующим образом:

delete ptr 

сбой приложения говорят, что я пытаюсь «для чтения или записи в защищенную память». Что мне делать?

ответ

1

Ну, управляемый объект может быть перемещен в памяти, поэтому компилятор не позволяет вам адресовать ему адрес - этот адрес будет устаревать рано или поздно.

Вы можете получить адрес управляемого объекта ссылочного типа после pinning it. Простейшим было бы использовать pin_ptr, объект будет гарантированно не перемещаться в памяти до тех пор, пока pin_ptr не выйдет из сферы действия.

Таким образом, вы можете написать это:

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

Но убедитесь, что NativeClass** не будет храниться вокруг и доступ к после призыв к native_init.


Что касается вашей попытки, это, безусловно, актуально. Но вы получаете AccessViolationException, скорее всего, потому, что native_init не использовал оператор new для создания объекта или использовал другое время выполнения. Если вы пытаетесь использовать библиотеку, она должна предоставить некоторую функцию native_free, поэтому используйте ее вместо delete.

+0

Нет, native_init использует новые, я могу это гарантировать. Исключение возникает, если я использую pinned ptr. – Ivan

+0

У вас также может быть проблема с двойным удалением, поэтому вы можете отладить это. Кроме того, убедитесь, что 'new' и' delete' используют одну и ту же базовую библиотеку времени выполнения. –

Смежные вопросы