2010-08-06 12 views
6

estoy tratando de llamar a la siguiente función en C++ que está envuelto en una DLL:¿Cómo puede Marshal una matriz de bytes en C#?

unsigned char * rectifyImage(unsigned char *pimg, int rows, int cols) 

Mi declaración de importación tiene el siguiente aspecto:

[DllImport("mex_rectify_image.dll")] 
unsafe public static extern IntPtr rectifyImage(
byte[] data, int rows, int columns); 

Y mi rutina de llamada tiene el siguiente aspecto:

byte[] imageData = new byte[img.Height * img.Width * 3]; 
// ... populate imageData 
IntPtr rectifiedImagePtr = rectifyImage(imageData, img.Height, img.Width); 
Byte[] rectifiedImage = new Byte[img.Width * img.Height * 3]; 
Marshal.Copy(rectifiedImagePtr, rectifiedImage, 0, 3 * img.Width * img.Height); 

Sin embargo, sigo obteniendo un error de ejecución:

Se produjo una primera excepción de tipo System.AccessViolationException en xxx.dll Se intentó leer o escribir en la memoria protegida. Esto a menudo es una indicación de que otra memoria está corrupta.

Me pregunto si el error radica en la forma en que estoy ordenando mis datos o en mi archivo DLL importado ... ¿alguien tiene alguna idea?

+0

Quizás quiera echar un vistazo a esta pregunta: http://stackoverflow.com/questions/289076/how-can-i-pass-a-pointer-to-an-array-using- p-invoke-in-c – Bobby

+1

Se supone que el valor de retorno de 'rectifyImage' se ha liberado, y si es así, ¿cómo? –

+0

El valor de retorno de rectifyImage se usa para crear un objeto de mapa de bits C#, y luego se libera. No he intentado averiguar cómo liberarlo realmente todavía. – Tim

Respuesta

2

Esto es probable que ocurra porque la convención de llamadas del método no es como lo está adivinando el Marshaller. Puede especificar la convención en el atributo DllImport.

No necesita la palabra clave 'inseguro' en la declaración de C# aquí ya que no es un código "inseguro". ¿Quizás lo estaba intentando con un puntero "fijo" en un punto y olvidó eliminar la palabra clave insegura antes de publicar?

1

no estoy seguro de si este es su problema, pero en general, los punteros de C++ se asignan a IntPtr. a fin de tratar de modificar su declaración de importación a esto:

[DllImport("mex_rectify_image.dll")] 
unsafe public static extern IntPtr rectifyImage(
IntPtr pData, int rows, int columns); 
+0

no estoy seguro de por qué me votaron a la baja, pero me tomé el tiempo para responder, así que al menos esperaba un comentario sobre por qué mi respuesta no es de su agrado. ¿Has probado mi sugerencia y no funcionó? –

0

rectifyImage está buscando un ponter a una de la primera bytes en un bloque de datos que se están enviando en el bloque. Pruebe imageData [0]

+0

Eso no va a funcionar, ya que el marshaller pasaría una copia del primer byte, en lugar de su referencia. Así que tendrías que usar un código inseguro para hacer eso, y pasar '& imageData [0]' en lugar de simplemente 'imageData [0]'. – Luaan

Cuestiones relacionadas