Garbage Collector в неуправляемом коде

300
30 января 2017, 17:02

Если я создам массив байт, например, и передам указатель на него в неуправляемый код, что с этим массивом будет делать Garbage Collector?

Answer 1

В C# это зависит от того, как вы передаёте массив в неуправляемый код.

Обычно сборщик мусора имеет право в любой момент переместить любой управляемый объект в памяти. Чтобы этого не произошло, вы должны прикрепить объект, чтобы сборщик мусора не пытался его переместить. Для этого существует несколько методов, например, ключевое слово fixed:

unsafe void F()
{
    int[] data = { 1, 2, 3 };
    fixed (int* p = &data[0])
    {
        // тут у вас есть указатель, можно передавать его в нативный код
    }
}

Понятно, данные будут закреплены лишь в области действия fixed, поэтому если вы запомните указатель в переменной и воспользуетесь им по окончанию блока fixed, ваша память может быть перемещена или собрана сборщиком мусора, и вы на пути к undefined behaviour, как в старые недобрые времена. Ответственность за корректность поведения unsafe-кода лежит на вас и только на вас.

Для ручной работы с адресами вам могут понадобиться IntPtr (для представления указателя в безопасном коде), GCHandle (для низкоуровневого обращения с объектами с точки зрения сборщика мусора) и особенно Marshal для ручного преобразования между нативными и управляемыми объектами.

Другой метод передавать нативной функции массив — вызов через P/Invoke. В этом случае то же самое делает за вас маршаллер. Вам придётся выписать правильную сигнатуру P/Invoke, наподобие такой:

void F(
    [MarshalAs(UnmanagedType.LPArray, SizeParamIndex=1)]
    long[] ar,
    int size);

(сигнатуры можно составить самому, вдумчиво почитав документацию, или подсмотреть сигнатуры для популярных функций WinAPI на http://pinvoke.net. Маршаллинг не может проверить правильность сигнатуры, поэтому если вы ошибётесь, последствия, думаю, понятны.

READ ALSO
Android Support Library

Android Support Library

Доброго времени сутокВозникла такая проблема, что в eclipse всё время вылезает ошибка:

361
java - Почему рекурсия так плоха?

java - Почему рекурсия так плоха?

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

500
Определить количество обратных слешей

Определить количество обратных слешей

Как в пути (например, d:\\WrkFld\\JJJ\\Адреса или d:\WrkFld\JJJ\Адреса) определить количество обратных слешей (\\ или \)?

286
Конвертировать double в int

Конвертировать double в int

Подскажите, как конвертировать double в int?

298