tags:

views:

148

answers:

2

hello all

i have following code , once i run my application i get this error

anyone know how i fix this error?

ERROR:

A call to PInvoke function 'testcamera!EDSDKLib.EDSDK::EdsDownloadEvfImage' has unbalanced the stack. 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

 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  A: 

When doing a platform invoke (P/Invoke), you have to tell the CLR what the parameters are (which determines how they get marshalled) as well as what the calling convention of the target native method is so that the runtime knows how to generate code to properly push arguments and cleanup the stack after the call. If the signatures do not match, you end up with runtime errors similar to what you're seeing.

The error message explains the issue well:

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

Compare the P/Invoke signature for EDSDK.EdsCreateEvfImageRef against the actual native method signature that implements this.

You can change the calling convention of the P/Invoke by specifying the CallingConvention property on the DllImport attribute. More than likely, the calling convention for EDSDK.EdsCreateEvfImageRef should match the calling convention of your other P/Invokes.

Chris Schmich
i put my dll import , [DllImport("EDSDK.dll")] public extern static uint EdsCreateEvfImageRef(IntPtr inStreamRef, out IntPtr outEvfImageRef); where is my code wrong?
user1400
What do your other P/Invokes look like? What does the native signature for `EdsDownloadEvfImage` look like?
Chris Schmich
I'm not sure where I can find this native code signature, I don't havethe source of my dll. I only got the dll itself
user1400
@user1400: In that case, you'll need some documentation to tell you. If this DLL is part of some SDK, I would expect it would come with a .h file or some other code description of the contents. If the DLL isn't from some SDK, then are you sure it's even possible (and legal) to call any functions it exports?
Daniel Pryden
its part of sdk (EDSDK 2.8 for canon camera) and it has some header file
user1400
A: 

Please use Cdecl calling convention for that function. Don't ask me why, it just works.

[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);   
lyxera