2010-04-01 7 views
3

J'ai une classe de wrapper de travail pour les appareils photo Dallmeier, Il contient une méthode de rappel pour recevoir l'image YUV en cours.
Voir les détails C# wrapper for array of three pointers. J'ai un bouton sur mon formulaire qui obtient l'image YUV. Le callback renvoie 'yuvData' qui est un tableau de trois pointeurs vers les parties Y, U et V de l'image. Je copie ensuite les trois pointeurs dans leur propre pointeur, puis les copie dans un tableau d'octets. Le yuvCallback continue de fonctionner jusqu'à ce que je déconnecte l'appareil photo.En utilisant Marshal.Copy correctement

Est-ce que j'utilise Marshal.Copy correctement?

public class DLMSDK 
{ 
    public delegate int YUVDataCallback(dlm_yuvdataParametersStructure pParameters); 

    DllImport(@"DallmeiersDLL\davidapileolive.dll")] 
     public extern static int dlm_setYUVDataCallback(int SessionHandle, YUVDataCallback dataCallback); 

     [StructLayout(LayoutKind.Explicit, Size = 32)] 
     public struct dlm_yuvdataParametersStructure 
     { 
      [FieldOffset(0)] 
      public int IPlayerID; 
      [FieldOffset(4), MarshalAs(UnmanagedType.ByValArray, SizeConst=3)] 
      public IntPtr[] yuvData; 
      [FieldOffset(8), MarshalAs(UnmanagedType.ByValArray, SizeConst=1)] 
      public IntPtr[] pitch; 
      [FieldOffset(12)] 
      public int width; 
      [FieldOffset(16)] 
      public int height; 
      [FieldOffset(18)] 
      public long ts; 
      [FieldOffset(28), MarshalAs(UnmanagedType.ByValArray, SizeConst = 1)] 
      public IntPtr[] extData; 
     } 
} 

public partical class Form1 : Form 
{ 
    int width; int height; 
    int yArraySize; int uvArraySize; 
    byte[] yBytes; byte[] uBytes; byte[] vBytes; 
    int sizeY; int sizeU; int sizeV; 
    IntPtr ptrY; IntPtr ptrU; IntPtr ptrV; 

    DLMSDK.YuvDataCallback yuvdataCallback; 

    private void Form1_Load(object send, EventArgs e) 
    { 
     error = DLMSDK.dlm_initSDK(); 
     if (error == 0) 
      registerEvents(); 
    } 

    private void registerEVents() 
    { 
     yuvdataCallback = yuvdataHandler; 
    } 

    private void btnGetYUV_Click(object sender, EventArgs e) 
    { 
     try 
     { 
       error = DLMSDK.dlm_setYUVDataCallback(SessionHandle, yuvdataCallback);  
     } 
     catch (Exception ex) 
     { 
       MessageBox.Show(ex.ToString()); 
     } 
    } 

    public int yuvdataHandler(DLMSDK.dlm_yuvdataParametersStructure pParameters) 
    { 
     width = pParameters.width; 
     height = pParameters.height; 
     yArraySize = width * height; 
     uvArraySize = yArraySize/4; 

     yBytes = new byte[yArraySize]; 
     uBytes = new byte[uvArraySize]; 
     vBytes = new byte[uvArraySize]; 

     sizeY = Marshal.SizeOf(yBytes[0]) * yBytes.Length; 
     ptrY = Marshal.AllocHGlobal(sizeY); 

     sizeU = Marshal.SizeOf(uBytes[0]) * uBytes.Length; 
     ptrU = Marshal.AllocHGlobal(sizeU); 

     sizeV = Marshal.SizeOf(vBytes[0]) * vBytes.Length; 
     ptrV = Marshal.AllocHGlobal(sizeV); 

     try 
     { 
      // Copy the three pointers to Y,U, & V pointers 
      Marshal.Copy(pParameters.yuvData, 0, ptrY, 1); 
      Marshal.Copy(pParameters.yuvData, 1, ptrU, 1); 
      Marshal.Copy(pParameters.yuvData, 2, ptrV, 1); 

      // Copy pointers to YUV byte arrays 
      Marshal.Copy(ptrY, yBytes, 0, sizeY); 
      Marshal.Copy(ptrU, uBytes, 0, sizeU); 
      Marshal.Copy(ptrV, vBytes, 0, sizeV); 

      // Convert Y (Luminance) to Greyscale and display 
      Bitmap bmp = ImgConvert.ToGreyscale(yBytes, width, height); 
      DisplayImage(bmp); 
     } 
     finally 
     { 
      if (ptrY != IntPtr.Zero) 
      { 
       Marshal.FreeHGlobal(ptrY); 
       ptrY = IntPtr.Zero; 
      } 
      if (ptrU != IntPtr.Zero) 
      { 
       Marshal.FreeHGlobal(ptrU); 
       ptrU = IntPtr.Zero; 
      } 
      if (ptrV != IntPtr.Zero) 
      { 
       Marshal.FreeHGlobal(ptrV); 
       ptrV = IntPtr.Zero; 
      } 
     } 

     return 0; 
    } 
} 

Répondre

2

Je vois que vous avez posté une question similaire sur les forums MSDN: http://social.msdn.microsoft.com/Forums/en-US/clr/thread/67d20c16-d58b-444d-9689-88fab2792ab1

Comme je l'ai écrit là-bas, ce n'est pas correct d'emballer les paramètres du délégué de rappel dans une structure et de le transmettre par valeur. La première étape consiste donc à corriger la signature du délégué.

+0

Ok corrigé la signature du délégué et tout fonctionne maintenant. – fergs

Questions connexes