2010-08-06 13 views
6

Je suis en train d'appeler la fonction C++ suivante qui est enveloppé dans une DLL:Comment pouvez-vous Marshal un tableau d'octets en C#?

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

Ma déclaration d'importation se présente comme suit:

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

Et ma routine d'appel se présente comme suit:

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); 

Cependant, je continue à obtenir une erreur d'exécution:

Une exception de première chance de type System.AccessViolationException s'est produite dans xxx.dll Vous avez tenté de lire ou d'écrire de la mémoire protégée. C'est souvent une indication que l'autre mémoire est corrompue. Je me demandais juste si la faute réside dans la façon dont je marshaling mes données ou dans mon fichier DLL importé ... quelqu'un a des idées?

+0

Vous voudrez peut-être jeter un oeil à cette question: http://stackoverflow.com/questions/289076/how-can-i-pass-a-pointer-to-an-array-using- p-invoke-in-c – Bobby

+1

La valeur de retour de 'rectifyImage' est-elle censée être libérée, et si oui, comment? –

+0

La valeur de retour de rectifyImage est utilisée pour créer un objet C# Bitmap, puis libérée. Je n'ai pas encore essayé de comprendre comment le libérer. – Tim

Répondre

2

Cela est probablement dû au fait que la convention d'appel de la méthode n'est pas celle que le marshaller est en train de deviner. Vous pouvez spécifier la convention dans l'attribut DllImport.

Vous n'avez pas besoin du mot-clé 'dangereux' dans la déclaration C# car il ne s'agit pas d'un code 'non sécurisé'. Peut-être que vous étiez en train de l'essayer avec un pointeur "fixe" à un moment donné et que vous avez oublié de supprimer le mot clé dangereux avant de le poster?

1

Vous ne savez pas si c'est votre problème, mais en général, les pointeurs C++ sont mappés sur IntPtr. alors essayez de modifier votre déclaration d'importation à ceci:

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

ne sais pas pourquoi je suis rejeté, mais j'ai pris le temps d'y répondre alors je m'attendrais au moins à un commentaire sur pourquoi ma réponse n'est pas à votre goût! avez-vous réellement essayé ma suggestion et cela n'a pas fonctionné? –

0

rectifyImage cherche un Ponter à un 1er octet dans un bloc de données que vous envoyez dans le bloc. Essayez imageData [0]

+0

Cela ne fonctionnera pas, puisque le marshaller passerait une copie du premier octet, plutôt que sa référence. Donc, vous devrez utiliser un code non sécurisé pour cela, et passez '& imageData [0]' plutôt que simplement 'imageData [0]'. – Luaan