6

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);
            }
3
  • 2
    please provide more information -dllimport, EdsDownloadEvfImage signature Commented Sep 20, 2010 at 7:34
  • this is my dllimport, [DllImport("EDSDK.dll")] public extern static uint EdsCreateEvfImageRef(IntPtr inStreamRef, out IntPtr outEvfImageRef); Commented Sep 20, 2010 at 7:51
  • 1
    and what is function native signature? Commented Sep 20, 2010 at 7:57

3 Answers 3

25

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);   
Sign up to request clarification or add additional context in comments.

1 Comment

Cdecl: The caller cleans the stack. This enables calling functions with varargs, which makes it appropriate to use for methods that accept a variable number of parameters. It makes each function call to include stack cleanup code. msdn.microsoft.com/en-us/library/…
3

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.

5 Comments

i put my dll import , [DllImport("EDSDK.dll")] public extern static uint EdsCreateEvfImageRef(IntPtr inStreamRef, out IntPtr outEvfImageRef); where is my code wrong?
What do your other P/Invokes look like? What does the native signature for EdsDownloadEvfImage look like?
I'm not sure where I can find this native code signature, I don't have the source of my dll. I only got the dll itself
@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?
its part of sdk (EDSDK 2.8 for canon camera) and it has some header file
3

I had the same issue as the poster, turned out I needed to change my project using the EDSDK library (v2.10) to use .NET 3.5 instead of .NET 4.0.

1 Comment

I also had the similar problem and got solved by making my version of .net to 3.5

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.