2011-12-16 10 views
7

Considere una estructura como System.Drawing.Point - una con LayoutKind.Sequential y que solo contenga miembros primitivos. Tengo una matriz de C# de tales estructuras.Matriz de estructuras de .NET a C++: ¿cuándo se copia?

Lo estoy pasando a una función (no administrada) de C++ a través de P/Invoke. En el lado de C++ hay una definición correspondiente de la estructura (por ejemplo, struct Point { int x, y; };). La función toma un Point* arg.

Mi pregunta es, ¿en qué casos el CLR copia los datos y en qué casos simplemente lo fija? Las variables incluyen:

  • tipo de matriz: unidimensional o rectangular
  • C# definición de la función - con ayuda de Point* o Point[]/Point[,]
  • usando fixed(Point* pointer = array) o no

quiero evitar la copiando porque es lento.

+0

No está documentado, las matrices simples simplemente quedan inmovilizadas. Use el depurador en caso de duda, escriba '* & array' para obtener la dirección de la matriz en C#. Y compare con el valor del puntero que obtiene en el código nativo. +8 en modo de 32 bits. –

Respuesta

0

Las estructuras se referencian por valor y las clases se referencian por referencia.

Significa que siempre tiene una estructura y realiza una asignación cuyos valores se copian, como cuando utiliza int a = b; a tiene el valor de b y no el punto tan b, por lo que si cambia el valor de a, b no se actualizará.

Si tiene una matriz, internamente almacena un vector de valores predeterminados, punteros para las clases y el valor predeterminado de la estructura para las estructuras. Tenga en cuenta que si la estructura contiene un miembro que es un tipo de referencia (clase), se almacena un puntero a nulo.

supose tiene

Point p = new Point(0, 1); 
Point[] pa = new Point[10]; 
pa[0] = p; 
++p.X; 

Desde el punto es una estructura (tipo de valor) al imprimir los valores

p: {1, 1} 
pa[0]: {0, 1} 
pa[1-9]: {0, 0} 

para C++ puede utilizar foo (Punto * PA) o foo (Point [] pa) para los mismos resultados; en C# use foo (Point [] pa) en una matriz de una dimensión. Para un foo rectangular (Point ** pa) en C++ y foo (Point [] []) en C#

+0

Esto realmente no responde la pregunta ... –

2

No tengo mucha experiencia con pinning, pero, de acuerdo con mi lectura de MSDN, tus estructuras deberían ser inmovilizado y no copiado. diseño

clases con formato blittable han fijado (formato) y co: referencias relevantes:

  1. Marshalling data with PInvoke
  2. Copying and pinning
  3. Blittable and non-blittable types
  4. Default marshalling for value types

desde el # 2 Representación de datos de mmon en memoria administrada y no administrada. Cuando estos tipos requieren referencias, un puntero al objeto en el montón se pasa directamente al destinatario.

Y su estructura de punto se da como un ejemplo en el n. ° 3, por lo que califica como tipo blittable.

Observé algunos objetos generales para fijar here, pero eso fue para un fixed byte[], que puede ser diferente a su Point[].

Cuestiones relacionadas