2010-09-20 11 views
6

he siguiente código, una vez que corro mi solicitud me sale este errorerror de la función que llama, [Una llamada a la función PInvoke desequilibró la pila]

Alguien sabe cómo puedo solucionar este error?

ERROR:

Una llamada a la función PInvoke 'testcamera EDSDKLib.EDSDK :: EdsDownloadEvfImage!' Ha desequilibrado la pila. Esto es probable porque la firma de PInvoke administrada no coincide con la firma de destino no administrada. Compruebe que la convención y los parámetros de la firma PInvoke llamadas coinciden con el objetivo de la firma no administrado

IntPtr cameraDev; 
      bool LVrunning = false; 
      uint err = EDSDK.EDS_ERR_OK; 
      uint device = 0; 
      IntPtr MemStreamRef = new IntPtr(0); 

      IntPtr EvfImageRef = new IntPtr(0); 
      PictureBox pbLV; 

      public LiveView(IntPtr c, PictureBox p) 
      { 
       cameraDev = c; 
       pbLV = p; 
      } 

      internal void StartLiveView() 
      { 
       //LVrunning = true; 
       //int i = 0; 

       // Get the output device for the live view image 
       err = EDSDK.EdsGetPropertyData(cameraDev, EDSDK.PropID_Evf_OutputDevice, 0, out device); 
       Debug.WriteLineIf(err != EDSDK.EDS_ERR_OK, String.Format("Get Property Data failed: {0:X}", err)); 
       Debug.WriteLineIf(err == EDSDK.EDS_ERR_OK, String.Format("Liveview output is: {0:x}", device)); 

       Thread.Sleep(1000); 

       // Set the computer as live view destination 
       if (err == EDSDK.EDS_ERR_OK) 
       { 
        err = EDSDK.EdsSetPropertyData(cameraDev, EDSDK.PropID_Evf_OutputDevice, 0, 
         Marshal.SizeOf(EDSDK.EvfOutputDevice_PC), EDSDK.EvfOutputDevice_PC); 
        Debug.WriteLine(String.Format("Liveview output to computer: {0:X}", err)); 
       } 

       // Create a memory stream for the picture 
       if (err == EDSDK.EDS_ERR_OK) 
       { 
        err = EDSDK.EdsCreateMemoryStream(0, out MemStreamRef); 
        Debug.WriteLine(String.Format("Create Memory Stream: {0:X}", err)); 
       } 

       // Get a reference to a EvfImage 

       if (err == EDSDK.EDS_ERR_OK) 
       { 

**//i get error here** 
        **err = EDSDK.EdsCreateEvfImageRef(MemStreamRef, out EvfImageRef);** 

        Debug.WriteLine(String.Format("Create Evf Imaage Ref: {0:X}", err)); 
       } 

       Thread.Sleep(2000); 
      } 
+2

favor proporcione más información -dllimport, EdsDownloadEvfImage firma – tom3k

+0

esta es mi dllimport, [DllImport ("EDSDK.dll")] extern pública uint estática EdsCreateEvfImageRef (IntPtr inStreamRef, fuera IntPtr outEvfImageRef); – user1400

+1

y ¿qué es la función de firma nativa? – tom3k

Respuesta

3

Cuando se realiza una invocación de plataforma (P/Invoke), lo que tiene que decir al CLR cuáles son los parámetros (que determina la forma en que obtienen marshalled) así como también lo que la convención de llamadas del método nativo de destino es para que el tiempo de ejecución sepa cómo generar código para insertar argumentos correctamente y limpiar la pila después de la llamada. Si las firmas no coinciden, terminas con errores de tiempo de ejecución similares a lo que estás viendo.

El mensaje de error explica el problema así:

This is likely because the managed PInvoke signature does not match the unmanaged target signature. Check that the calling convention and parameters of the PInvoke signature match the target unmanaged signature

comparar el P/Invoke firma para EDSDK.EdsCreateEvfImageRef contra la firma del método nativo real que implementa esto.

Puede cambiar la convención de llamadas de la P/Invocación especificando la propiedad CallingConvention en el atributo DllImport. Lo más probable es que la convención de llamadas para EDSDK.EdsCreateEvfImageRef debe coincidir con la convención de llamadas de sus otras P/invocaciones.

+0

puse mi importación dll, [DllImport ("EDSDK.dll")] public extern static uint EdsCreateEvfImageRef (IntPtr inStreamRef, out IntPtr outEvfImageRef); ¿Dónde está mi código equivocado? – user1400

+0

¿Cómo se ven tus otros P/Invocaciones? ¿Cómo se ve la firma nativa de 'EdsDownloadEvfImage'? –

+0

No estoy seguro de dónde puedo encontrar esta firma de código nativo, no tengo la fuente de mi dll. Solo obtuve el dll – user1400

24

Utilice la convención de llamadas Cdecl para esa función. No me preguntes por qué, simplemente funciona.

[DllImport("EDSDK.dll", CallingConvention=CallingConvention.Cdecl)] 
public extern static uint EdsCreateEvfImageRef(IntPtr inStreamRef, out IntPtr outEvfImageRef); 

[DllImport("EDSDK.dll",CallingConvention=CallingConvention.Cdecl)] 
public extern static uint EdsDownloadEvfImage(IntPtr inCameraRef, IntPtr outEvfImageRef); 
+0

¡gracias por esa pista útil! – esskar

+3

'Cdecl': la persona que llama limpia la pila. Esto permite llamar funciones con varargs, lo que hace que sea apropiado usarlo para métodos que aceptan una cantidad variable de parámetros. Hace que cada función llame para incluir el código de limpieza de la pila. http://msdn.microsoft.com/en-us/library/system.runtime.interopservices.callingconvention.aspx – nunespascal

2

que tenían el mismo problema que el cartel, resultó que tenía que cambiar mi proyecto utilizando la biblioteca EDSDK (v2.10) para utilizar .NET 3.5 en lugar de 4.0 .NET.

+0

También tuve el problema similar y me solucionaron haciendo mi versión de .net a 3.5 – Anand

Cuestiones relacionadas