Уничтожить неуправляемый объект из кода .NET - PullRequest
1 голос
/ 28 сентября 2011

Я написал библиотеку C ++, которая предоставляется моему приложению VB.NET через оболочку C ++ / CLI.

Я беспокоюсь об объектах, которые я передаю приложению VB.NET через оболочку. Чтобы использовать классы в библиотеке, я написал для них оболочки, а классы-оболочки содержат указатели на неуправляемый экземпляр класса. В деструкторе класса-оболочки я удаляю память, на которую указывает неуправляемый указатель.

Если обернутая библиотека .NET передает один из этих экземпляров класса в приложение VB.NET, а приложение VB.NET использует его и перемещается (не сохраняет ссылку на него); соберется ли сборщик мусора .NET и избавится от этого экземпляра класса, что приведет к освобождению неуправляемой памяти в деструкторе класса? Это вызвало бы ошибку, если бы у меня была ссылка на ту же самую память, на которую указывал упакованный экземпляр класса.

Если это так, то я просто скопирую все данные в обертке, чтобы мои обертки не передавали какие-либо данные в собственную часть библиотеки. Если это не так, то нужно ли мне вызывать какой-либо метод dispose для экземпляра обернутого класса, чтобы уничтожить неуправляемый объект?

Ответы [ 2 ]

1 голос
/ 28 сентября 2011

В CLI вам просто нужно использовать синтаксис деструктора (~MyClass()), и компилятор C ++ / CLI создаст для вас реализацию IDisposable в классе.

Этот "деструктор" (на самом деле это не так, он просто имеет синтаксис ) будет вызываться, когда в неуправляемом коде вызывается метод Dispose . Именно здесь вы могли бы сделать вызовы, которые вам нужно сделать, чтобы освободить ресурсы.

Если вы хотите реализовать финализатор, вы должны использовать новый синтаксис деструктора (!MyClass()). Это должно высвободить те же ресурсы, что и в вашем «деструкторе».

Наконец, в вашем управляемом коде вы просто ссылаетесь на реализацию IDisposable, а затем вызываете Dispose, скорее всего, с помощью оператора using .

0 голосов
/ 28 сентября 2011

Вы немного смешиваете это. Да, после того, как код vb.net перестанет ссылаться на один из ваших классов C ++ / CLI, тогда в конечном итоге будет вызван финализатор после того, как объект будет собран. Обратите внимание, что это финализатор , он не имеет никакого отношения к утилизации. Ваш объект C ++ / CLI должен содержать как деструктор (вызываемый Dispose ()), так и финализатор.

В противном случае нет опасности повреждения памяти. Финализатор вызывается только тогда, когда сборщик мусора не может найти никаких живых ссылок на объект. Поскольку не осталось ссылки, нет никакого способа, которым вы можете случайно получить доступ к удаленному нативному объекту. Проверьте этот ответ для стандартного образца.

...