2010-02-07 9 views
24

Supongamos que está llamando a una función Win32 que completará su matriz de bytes. Usted crea una matriz de tamaño 32, vacía. Luego pásalo a la función de Win32 para que se llene int, y úsala más tarde en tu código administrado. ¿Existe la posibilidad de que la matriz de bytes se mueva o sobrescriba entre el momento en que se asignó y la función Win32 la completa?Al pasar una matriz de bytes gestionados [] a través de PInvoke para que Win32 la rellene, ¿necesita ser anclado?

Respuesta

34

respuesta corta: No, los clavos no es necesario en este caso

más larga respuesta:

El CLR Clavaré automáticamente las referencias a objetos administrados cuando la cruz del límite PInvoke. Tan pronto como la función PInvoke salga, la referencia se destrabará. Por lo tanto, en situaciones como tener una función nativa, complete un byte[], no es necesario fijar manualmente porque el objeto solo se usa por código nativo durante la llamada a la función.

La fijación manual de la matriz es necesaria si el código nativo almacena en caché el puntero administrado. Cuando esto sucede, debe fijar manualmente la matriz hasta que el código nativo ya no necesite el puntero. En este caso supongo que el puntero no se almacena en caché por lo tanto, no es necesario fijar

Referencia - http://msdn.microsoft.com/en-us/magazine/cc163910.aspx#S2

+0

Ok, entonces la pregunta es ¿qué sucede cuando la llamada de Win32 no regresa inmediatamente? Digamos, por ejemplo, una llamada a ReadFile() que usa E/S superpuestas y un evento de restablecimiento manual. La llamada vuelve inmediatamente, mientras se realiza la operación de E/S. ¿La matriz de bytes debe estar anclada en ese caso? ¿Cómo se sabe si la biblioteca nativa está almacenando en caché la matriz –

+1

? Bueno, debería haber leído primero el enlace porque da como resultado ReadFileEx y I/O solapada como un ejemplo de cuándo necesitaría fijar. –

0

Lamento contestar mi propia pregunta, pero creo que si el tipo es blittable, como byte [] es, entonces la matriz se anclaría mientras el tiempo de ejecución lo ordenara, por lo que no sería necesario inmovilizar. Un objeto en el otro momento sería diferente. Por favor corrígeme si estoy equivocado.

+1

¿Cuál es la mejor manera de fijar un byte [] en C#? –

+1

Fija un byte [] utilizando la palabra clave 'fixed' dentro de un bloque de código' inseguro'. Ver http://msdn.microsoft.com/en-us/library/f58wzh21(VS.71).aspx –

+1

@Reed: Creo que está aquí. El código Marshaller fijará la matriz durante la llamada de manufacturado a nativo, por lo que la matriz solo tendrá que ser anclado explícitamente si quiere hacer referencia a ella en el código nativo en otro momento. –

2

acuerdo con MSDN Marshaling Arrays of Types solamente una matriz pasada por referencia se puede escribir el código no administrado. Por lo tanto, parece que debe declarar el parámetro de matriz [out] o [in, out] si desea completarlo en el lado no administrado.

Esta página http://msdn.microsoft.com/en-us/library/aa719896(VS.71).aspx las arregla para seguir y seguir sin decir explícitamente que los pasadores Marshaller las matrices durante la llamada de las arreglaron para no administrado, pero gran parte de lo que describe no funcionaría si el contador de referencias no PIN.

Cuestiones relacionadas