2009-12-16 14 views
7

Estoy tratando de crear una matriz administrada de dobles a partir de una matriz de bytes. Tengo el problema trabajando actualmente, pero quería optimizar. Aquí hay un código que me gustaría trabajar:C# - Crear matriz administrada desde el puntero

private unsafe static double[] _Get_Doubles(byte[] _raw_data) 
{ 
    double[] ret; 
    fixed (byte* _pd = _raw_data) 
    { 
     double* _pret = (double*)_pd; 
     ret = (double[])*_pret; //FAILURE 
    } 
} 

Háganme saber cómo hacer frente a estos problemas.

-Aaron

+0

En general cuando se trata de la interoperabilidad, el Marshaller es su amigo, a su servicio en System.Runtime.InteropServices.Marshal. No sé, sin embargo, qué necesita específicamente para usar arreglos. Sin embargo, puede acceder a matrices con aritmética de puntero. Tal vez esto te indique la dirección correcta. – OregonGhost

+0

@daGhost - Sin duda conozco el acceso a matrices con punteros, pero tendré que buscar una matriz administrada. Gracias. –

+0

@Limited Thing (No me vuelvas a llamar daGhost): si puedes acceder a los elementos de la matriz con punteros, puedes copiar los valores en una matriz administrada. – OregonGhost

Respuesta

2

Justo ahora, pensé que stackalloc sería la manera correcta, pero falla. Lo más importante, ahora sé que estaba condenado al fracaso. No hay forma de hacer lo que quiero hacer.

Esto se puede ver mediante la reformulación de la pregunta:

¿Cómo puedo crear una matriz administrada alrededor de un array 'insegura'?

Dado que una matriz administrada tiene información de encabezado (porque es una clase en torno a una tirada de memoria), requiere más espacio en memoria que la matriz misma. Entonces, la respuesta es:

Asignar el espacio antes (y/o después? Según la forma en que se almacenan las matrices administradas en la memoria) la matriz misma y poner la información administrada (longitud, (etcétera)) alrededor del 'inseguro 'array.

Esto no es posible porque para garantizar que hay suficientes datos alrededor de la matriz es inestable en el mejor de los casos. En mi ejemplo particular, puede haber suficiente espacio porque se pasa un byte administrado [], lo que significa que hay datos alrededor de la matriz, pero afirmar que los mismos datos son apropiados para double administrado [] es dudoso en el mejor de los casos, pero la mayoría probablemente erróneo, y cambiar los datos para que sea apropiado para el doble administrado [] es nefasto.

[EDIT]

Parece que Marshal.Copy es el camino a seguir aquí. Crear una nueva matriz y dejar Mariscal copiarlos (la esperanza de que será más rápido que yo, o que tal vez en una fecha posterior, que será más rápido):

var ret = new double[_raw_data.Length/sizeof(double)]; 
System.Runtime.InteropServices.Marshal.Copy(new System.IntPtr(_pret), ret, 0, ret.Length); 
3

Una de las principales cosas que notará sobre el código que has publicado es que no hay manera de saber cuántos elementos se apunta el valor de retorno, y una matriz administrada tiene que saber cómo grande es. Puede devolver un double* o crear un new double[XXX] y copiar los valores o incluso (si el recuento es constante) crear un struct con un miembro public fixed double _data[2]; y convertir los datos sin procesar a ese tipo.

+0

Eso es básicamente lo que terminé haciendo. Creé el arreglo doble con una longitud fija, luego copié mis valores allí de a uno por vez. Sería bueno, de forma C++, no asignar la nueva matriz doble. Sí, una estructura con un doble [] y un byte [] establecido para superponerse como los registros al, ax y eax, pero la sobrecarga de crear una estructura podría ser más de lo que estoy haciendo ... lo que podría hacerte piensa, ¿por qué querrías ser tan intrincado en tu copia de matriz? A lo que respondo ''. –

Cuestiones relacionadas