2010-09-20 50 views
6

tôi có mã sau đây, khi tôi chạy ứng dụng của mình, tôi nhận được lỗi nàychức năng gọi lỗi, [Cuộc gọi đến chức năng PInvoke không cân bằng chồng]

bất cứ ai biết cách sửa lỗi này?

LỖI:

Một cuộc gọi đến chức năng PInvoke 'testcamera EDSDKLib.EDSDK :: EdsDownloadEvfImage!' Có không cân bằng stack. Điều này có thể do chữ ký PInvoke được quản lý không khớp với chữ ký đích không được quản lý. Kiểm tra xem quy ước gọi và các thông số của chữ ký PInvoke phù hợp với mục tiêu không được quản lý chữ ký

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

vui lòng cung cấp thêm thông tin -dllimport, EdsDownloadEvfImage chữ ký – tom3k

+0

đây là dllimport tôi, [DllImport ("EDSDK.dll")] extern public static uint EdsCreateEvfImageRef (IntPtr inStreamRef, ra IntPtr outEvfImageRef); – user1400

+1

và chữ ký gốc chức năng là gì? – tom3k

Trả lời

3

Khi làm một nền tảng invoke (P/Invoke), bạn phải nói với CLR những gì các thông số (mà quyết định làm thế nào họ có được marshalled) cũng như quy ước gọi của phương thức gốc đích là sao cho thời gian chạy biết cách tạo mã để đẩy đối số đúng cách và dọn dẹp ngăn xếp sau cuộc gọi. Nếu chữ ký không khớp, bạn kết thúc với các lỗi thời gian chạy tương tự như những gì bạn đang thấy.

Thông báo lỗi giải thích vấn đề này cũng:

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

Hãy so sánh P/Gọi chữ ký cho EDSDK.EdsCreateEvfImageRef so với chữ ký phương pháp có nguồn gốc thực tế mà thực hiện này.

Bạn có thể thay đổi quy ước gọi của P/Invoke bằng cách chỉ định thuộc tính CallingConvention trên thuộc tính DllImport. Nhiều hơn khả năng, quy ước gọi điện thoại cho EDSDK.EdsCreateEvfImageRef phải khớp với quy ước gọi điện của các P/Invokes khác của bạn.

+0

tôi đặt dll của tôi nhập khẩu, [DllImport ("EDSDK.dll")] công khai extern tĩnh uint EdsCreateEvfImageRef (IntPtr inStreamRef, ra IntPtr outEvfImageRef); mã của tôi ở đâu sai? – user1400

+0

P/Invokes của bạn trông như thế nào? Chữ ký gốc cho 'EdsDownloadEvfImage' trông như thế nào? –

+0

Tôi không chắc chắn nơi tôi có thể tìm thấy chữ ký mã gốc này, tôi không có nguồn của dll của tôi. Tôi chỉ có dll chính nó – user1400

24

Vui lòng sử dụng quy ước gọi điện của Cdecl cho chức năng đó. Đừng hỏi tôi tại sao, nó chỉ hoạt động.

[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

nhờ gợi ý hữu ích đó! – esskar

+3

'Cdecl': Người gọi dọn dẹp ngăn xếp. Điều này cho phép các hàm gọi bằng varargs, điều này làm cho nó thích hợp để sử dụng cho các phương thức chấp nhận một số biến của các tham số. Nó làm cho mỗi hàm gọi để bao gồm mã ngăn xếp ngăn xếp. http://msdn.microsoft.com/en-us/library/system.runtime.interopservices.callingconvention.aspx – nunespascal

2

Tôi đã gặp vấn đề tương tự như áp phích, hóa ra tôi cần thay đổi dự án của mình bằng thư viện EDSDK (v2.10) để sử dụng .NET 3.5 thay vì .NET 4.0.

+0

Tôi cũng gặp vấn đề tương tự và đã được giải quyết bằng cách tạo phiên bản .net thành 3.5 – Anand

Các vấn đề liên quan