Como otros han mencionado, no hay manera que puede almacenar los datos en un administradobyte[]
sin copiar (con la estructura actual que nos ha facilitado *). Sin embargo, si realmente no necesita en un búfer administrado, puede usar las operaciones unsafe
para trabajar directamente con la memoria no administrada. Realmente depende de lo que necesites hacer con eso.
Todos byte[]
y otros tipos de referencia son gestionados por el recopilador de basura CLR, y esto es lo que es responsable de la asignación de memoria y la desasignación cuando ya no se utiliza. La memoria apuntada por el retorno de GetBuffer
es un bloque de memoria no administrada asignada por el código C++ y (detalles de implementación/diseño de memoria aparte) es esencialmente completamente independiente de la memoria administrada por GC. Por lo tanto, si desea utilizar un tipo de CLR gestionado por GC (byte[]
) para contener todos los datos actualmente almacenados en su memoria no administrada a la que apunta su IntPtr
, debe moverse (copiarse) a la memoria que el GC conoce. Esto se puede hacer por Marshal.Copy
o por un método personalizado usando el código unsafe
o pinvoke o lo que sea.
Sin embargo, depende de lo que quiera hacer con él. Has mencionado que son datos de video. Si desea aplicar alguna transformación o filtro a los datos, probablemente pueda hacerlo directamente en el búfer no administrado. Si desea guardar el búfer en el disco, probablemente pueda hacerlo directamente en el búfer no administrado.
Sobre el tema de la longitud, no hay forma de saber la longitud de un búfer de memoria no administrado a menos que la función que asignó el búfer también le indique cuál es la longitud. Esto se puede hacer de muchas maneras, como lo han mencionado los comentaristas (primer campo de la estructura, apartado del método).
* Finalmente, si tiene control del código C++, podría ser posible modificarlo para que no sea responsable de asignar el búfer al que escribe los datos, y en su lugar se le proporciona un puntero a un búfer preasignado. A continuación, puede crear un administradobyte[]
en C#, preasignado al tamaño requerido por su código C++, y utilizar el tipo GCHandle
para fijarlo y proporcionar el puntero a su código C++.
¡Debería copiar los datos porque el 'IntPtr' apunta a * memoria no administrada *! – Yahia
Gracias por su rápida respuesta, pero ese IntPtr fue devuelto desde la función de exportación C++, por lo que puedo administrarlo y eliminarlo en cualquier lugar que desee. No quiero copiar los datos porque los datos son búfer de video, por lo que es muy grande. La copia tendrá un mal rendimiento. ¡Gracias! – TTGroup
Eso realmente no es razón para ir por prácticas inseguras ... realmente debe copiar el contenido; hay varios métodos seguros para hacerlo (algunos más rápidos que otros) ... – Yahia