Уничтожить неуправляемый объект из кода.NET
Я написал библиотеку C++, которая предоставляется моему приложению VB.NET через оболочку C++/CLI.
Я беспокоюсь об объектах, которые я перемещаю в приложение VB.NET через оболочку. Чтобы использовать классы в библиотеке, я написал для них оболочки, а классы-оболочки содержат указатели на неуправляемый экземпляр класса. В деструкторе класса-оболочки я удаляю память, на которую указывает неуправляемый указатель.
Если обернутая библиотека.NET передает один из этих экземпляров класса в приложение VB.NET, а приложение VB.NET использует его и перемещается (не сохраняет ссылку на него); соберется ли сборщик мусора.NET и избавится от этого экземпляра класса, что приведет к освобождению неуправляемой памяти в деструкторе класса? Это вызвало бы ошибку, если бы у меня была ссылка на ту же самую память, на которую указывал упакованный экземпляр класса.
Если это так, то я просто скопирую все данные в обертке, чтобы мои обертки не передавали какие-либо данные в нативную часть библиотеки. Если это не так, то нужно ли мне вызывать какой-либо метод dispose для экземпляра обернутого класса, чтобы уничтожить неуправляемый объект?
2 ответа
Вы немного смешиваете это. Да, после того, как код vb.net перестанет ссылаться на один из ваших классов C++/CLI, в конце концов финализатор будет вызван после того, как объект будет собран. Обратите внимание, что это финализатор, он не имеет никакого отношения к утилизации. Ваш объект C++/CLI должен содержать как деструктор (вызываемый Dispose()), так и финализатор.
В противном случае нет опасности повреждения памяти. Финализатор вызывается только тогда, когда сборщик мусора не может найти никаких живых ссылок на объект. Так как не осталось никакой ссылки, вы не сможете случайно получить доступ к удаленному нативному объекту. Проверьте этот ответ для стандартного образца.
В CLI вы просто должны использовать синтаксис деструктора (~MyClass()
) и компилятор C++/CLI создаст IDisposable
реализация на уроке для вас.
Этот "деструктор" (на самом деле это не так, он имеет только один синтаксис) будет вызван, когда Dispose
метод вызывается в неуправляемом коде. Именно здесь вы можете сделать вызовы, которые вам нужно сделать, чтобы освободить ресурсы.
Если вы хотите реализовать финализатор, вы должны использовать новый синтаксис деструктора (!MyClass()
). Это должно высвободить те же ресурсы, что и в вашем "деструкторе".
Наконец, в вашем управляемом коде вы просто ссылаетесь на IDisposable
реализация, а затем позвоните Dispose
на нем, скорее всего, через using
заявление.