2010-10-31 7 views

Répondre

3

Vous devez connaître le nombre exact d'octets renvoyés et les dimensions de l'image bitmap (hauteur, largeur et codage). Ensuite, vous pouvez déclarer en C# comme:

[DllImport("yourlib.dll")] 
private static extern IntPtr GetCurrentImage(); 

IntPtr que vous obtenez de qui peut être utilisé avec Marshal.Copy, pour obtenir les octets bruts:

byte[] buffer = new byte[length]; 
IntPtr beginPtr = GetCurrentImage(); 
Marshal.Copy(beginPtr, buffer,0,length); 

Enfin, déclarer une Bitmap avec les dimensions de votre image et le PixelFormat utilisé (s'il s'agit d'un format de pixel non standard, vous devrez peut-être effectuer une conversion vous-même). Ensuite, vous pouvez copier les données dans les octets bitmap bruts, en utilisant LockBits pour obtenir une instance BitmapData qui pointe vers les données bitmap brutes.

+0

Et qui va se débarrasser de la mémoire allouée par 'GetCurrentImage()'? – Timwi

+0

@Timwi, bien sûr cela dépend du contrat défini dans la DLL externe. Peut-être y a-t-il une fonction à faire qui soit déjà disponible, ou peut-être qu'il faut l'ajouter. Mais bien sûr, le PO devra le prendre en considération. Si la mémoire a été allouée en utilisant LocalAlloc dans le code non managé, on peut utiliser Marshal.FreeHGlobal dans le code managé pour le libérer. – driis

+0

Got it ... la seule chose qui n'était pas vraiment plausible est que le format d'image 24bppRGB est BGR, pas RGB – Thomas

0

La stratégie commune pour des choses comme ceci est de passer dans un tampon et avoir la fonction remplir le tampon. Sinon, vous rencontrez des problèmes avec la disposition de la mémoire allouée; en d'autres termes, vous aurez une fuite de mémoire.

Vous devriez donc avoir des fonctions C comme celui-ci ...

uint32_t _stdcall GetCurrentImageSize(); 
void _stdcall GetCurrentImage(uint8_t* buffer, int offset, int bufferSize); 

Et puis en C# vous feriez quelque chose comme ...

var buffer = new byte [ GetCurrentImageSize() ]; 
fixed (byte* b = &buffer[0]) 
    GetCurrentImage(b, 0, buffer.Length); 

// 'buffer' now contains the image 
0

Si vous voulez continuer à travailler dans un contexte dangereux, même en C#, vous pouvez également simplifier tout en contournant le maréchal et IntPtrs comme suit:

[DllImport("Library.dll")] 
internal static unsafe extern Byte* GetCurrentImage(); 

Gardez à l'esprit que c'est toujours une bonne pratique d'insérer toutes vos importations dans une classe statique appelée NativeMethods et de les déclarer comme internes.

Questions connexes