2010-09-20 5 views
6

i Code verfolgt haben, sobald ich meine Anwendung ausführen bekomme ich diesen FehlerFehlerfunktion aufrufen, [Ein Aufruf PInvoke Funktion unausgewogen den Stapel]

Wer weiß, wie ich diesen Fehler beheben?

ERROR:

Ein Aufruf von PInvoke Funktion 'testcamera EDSDKLib.EDSDK :: EdsDownloadEvfImage!' Hat unausgewogen den Stapel. Dies liegt wahrscheinlich daran, dass die verwaltete PInvoke-Signatur nicht mit der nicht verwalteten Zielsignatur übereinstimmt. Überprüfen Sie, ob die Aufrufkonvention und die Parameter der PInvoke Signatur des Ziel entsprechen nicht verwalteten Signatur

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

bitte weitere Informationen -dllimport liefern, EdsDownloadEvfImage Unterschrift – tom3k

+0

das ist mein Dllimport [DllImport ("EDSDK.dll")] öffentliche extern statisch uint EdsCreateEvfImageRef (IntPtr inStreamRef, aus IntPtr outEvfImageRef); – user1400

+1

und was ist Funktion native Signatur? – tom3k

Antwort

3

Wenn eine Plattform invoke tun (P/Invoke), haben Sie die CLR sagen, was die Parameter (die bestimmt, wie sie erhalten marshalled) sowie die Aufrufkonvention der nativen Zielmethode, sodass die Laufzeitumgebung weiß, wie Code generiert wird, um Argumente ordnungsgemäß auszugeben und den Stack nach dem Aufruf zu bereinigen. Wenn die Signaturen nicht übereinstimmen, haben Sie Laufzeitfehler, die denen ähneln, die Sie sehen.

Die Fehlermeldung erklärt das Problem gut:

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

Vergleichen Sie die P/Invoke Signatur für EDSDK.EdsCreateEvfImageRef gegen die tatsächlichen native Methode Signatur, die diese implementiert.

Sie können die Aufrufkonvention von P/Invoke ändern, indem Sie die CallingConvention-Eigenschaft für das Attribut DllImport angeben. Sehr wahrscheinlich sollte die Aufrufkonvention für mit der Aufrufkonvention Ihrer anderen P/Invokes übereinstimmen.

+0

Ich setze meinen DLL-Import, [DllImport ("EDSDK.dll")] öffentlichen externen Static Uint EdsCreateEvfImageRef (IntPtr inStreamRef, out IntPtr outEvfImageRef); wo ist mein Code falsch? – user1400

+0

Wie sehen Ihre anderen P/Invokes aus? Wie sieht die native Signatur für "EdsDownloadEvfImage" aus? –

+0

Ich bin mir nicht sicher, wo ich diese native Code-Signatur finden kann, ich habe keine Quelle meiner DLL. Ich habe nur die DLL selbst – user1400

24

Verwenden Sie die Cdecl-Aufrufkonvention für diese Funktion. Frag mich nicht warum, es funktioniert einfach.

[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

danke für diesen nützlichen Hinweis! – esskar

+3

'Cdecl': Der Aufrufer bereinigt den Stapel. Dadurch können Funktionen mit varargs aufgerufen werden, was es sinnvoll macht, sie für Methoden zu verwenden, die eine variable Anzahl von Parametern akzeptieren. Es macht jeden Funktionsaufruf, Stack Cleanup-Code enthalten. http://msdn.microsoft.com/en-us/library/system.runtime.interopservices.callingconvention.aspx – nunespascal

2

Ich hatte das gleiche Problem wie das Plakat, stellte sich heraus, I 4.0 .NET 3.5 anstelle von .NET zu verwenden, benötigt, um mein Projekt mit dem EDSDK Bibliothek (v2.10) zu ändern.

+0

Ich hatte auch das ähnliche Problem und wurde gelöst, indem ich meine Version von .net auf 3.5 – Anand