Ответ 1
Как уже упоминалось, невозможно сохранить данные в управляемом byte[]
без копирования (с текущей структурой, которую вы предоставили *). Однако, если вам действительно не нужно, чтобы он находился в управляемом буфере, вы можете использовать операции unsafe
для работы непосредственно с неуправляемой памятью. Это действительно зависит от того, что вам нужно с этим делать.
Все byte[]
и другие ссылочные типы управляются сборщиком мусора CLR, и именно это отвечает за выделение памяти и освобождение, когда она больше не используется. Память, на которую указывает возврат GetBuffer
, представляет собой блок неуправляемой памяти, выделенный кодом С++ и (в сторону макета памяти/подробности реализации в стороне) по существу полностью отделен от вашей управляемой памяти GC. Поэтому, если вы хотите использовать CLR-тип, управляемый GC (byte[]
), чтобы содержать все данные, находящиеся в настоящее время в вашей неуправляемой памяти, на которые указывает ваш IntPtr
, его необходимо переместить (скопировать) в память, которую знает GC около. Это можно сделать с помощью Marshal.Copy
или с помощью настраиваемого метода с использованием кода unsafe
или pinvoke или того, что у вас есть.
Однако это зависит от того, что вы хотите с ним делать. Вы упомянули о видеоданных. Если вы хотите применить какое-то преобразование или фильтр к данным, вы, вероятно, можете сделать это непосредственно в неуправляемом буфере. Если вы хотите сохранить буфер на диск, вы можете сделать это непосредственно в неуправляемом буфере.
По теме длины нет способа узнать длину неуправляемого буфера памяти, если функция, которая выделила буфер, также не сообщит вам, что такое длина. Это можно сделать многими способами, как отмечали комментаторы (первое поле структуры, вне параметров по методу).
* Наконец, если у вас есть контроль над кодом на С++, возможно, его можно будет изменить, чтобы он не отвечал за выделение буфера, в который он записывает данные, и вместо этого снабжен указателем на предварительно выделенный буфер. Затем вы могли бы создать управляемый byte[]
в С#, предварительно выделенный для размера, необходимого вашему С++-коду, и использовать тип GCHandle
для вывода это и указать указатель на ваш код на С++.