2010-08-06 12 views
6

sto cercando di chiamare la seguente funzione C++ che è avvolto in una DLL:Come si può Marshal un array di byte in C#?

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

La mia dichiarazione di importazione è simile al seguente:

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

E la mia routine di chiamata è simile al seguente:

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

Tuttavia, continuo a ricevere un errore di runtime:

Si è verificata una prima eccezione di tipo System.AccessViolationException in xxx.dll Tentativo di leggere o scrivere memoria protetta. Questo è spesso un'indicazione che un'altra memoria è corrotta.

Mi chiedo solo se il problema sta nel modo in cui eseguo il marshalling dei miei dati o nel mio file DLL importato ... qualcuno ha qualche idea?

+0

Si potrebbe dare un'occhiata a questa domanda: http://stackoverflow.com/questions/289076/how-can-i-pass-a-pointer-to-an-array-using- p-invoke-in-c – Bobby

+1

Il valore restituito da 'rectifyImage' dovrebbe essere liberato e, in caso affermativo, come? –

+0

Il valore di ritorno per rectifyImage viene utilizzato per creare un oggetto Bitmap C# e quindi liberato. Non sono riuscito a cercare di capire come effettivamente liberarlo ancora. – Tim

risposta

2

È probabile che ciò si verifichi perché la convenzione di chiamata del metodo non è come il marshaller sta indovinando che sia. È possibile specificare la convenzione nell'attributo DllImport.

Non hai bisogno della parola chiave "non sicura" nella dichiarazione C# qui perché non è un codice "non sicuro". Forse lo stavi provando con un puntatore "fisso" a un certo punto e hai dimenticato di rimuovere la parola chiave non sicura prima di postarla?

1

non sicuro se questo è il tuo problema, ma in generale i puntatori C++ mappano a IntPtr. in modo da provare modificare la sua dichiarazione di importazione a questo:

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

non sono sicuro del motivo per cui sto per essere votato, ma ho avuto il tempo di rispondere a questo quindi mi aspetto almeno un commento sul perché la mia risposta non è di tuo gradimento! hai effettivamente provato il mio suggerimento e non ha funzionato? –

0

rectifyImage è alla ricerca di un Ponter ad un 1 ° di byte in un blocco per i dati da inviare nel blocco. Prova imageData [0]

+0

Non funzionerà, poiché il marshaller passerebbe una copia del primo byte, anziché il suo riferimento. Quindi dovresti usare un codice non sicuro per farlo e passare '& imageData [0]' piuttosto che solo 'imageData [0] '. – Luaan

Problemi correlati