0

I am using the uEye API (Dll) to record video from the live camera. I got it working on .NET 6, but for a reason I had to switch to .NET Framework 4.8.1. And now it's throwing this: Managed Debugging Assistant 'PInvokeStackImbalance'.

Full details of the error:

Managed Debugging Assistant 'PInvokeStackImbalance' Message=Managed Debugging Assistant 'PInvokeStackImbalance' : 'A call to PInvoke function 'uEyeDotNet!uEye.Tools.Video+ToolsWrapper::InitAviX86' 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.'

private void btnRecord_Click(object sender, EventArgs e)
    {
        try
        {
            string filename = DateTime.Now.ToString("yyyy-dd-M--HH-mm-ss") + ".avi";
            camera.Video.Start(procedure_path + "/videos/" + filename);
        }
        catch (Exception)
        {
            throw;
        }
    }

Code from the DLL:

public Status Start(string strFileName)
    {
        Status status = Status.Success;
        if (m_VideoHandle.Init(m_CamParent, out s32VideoID) == Status.Success)
        {
            m_bInitialize = true;
        }

        if (m_bInitialize && !m_bRunning)
        {
            new PixelFormat(m_CamParent).Get(out var mode);
            Memory memory = new Memory(m_CamParent);
            memory.GetActive(out int s32MemId);
            memory.GetSize(s32MemId, out var size);
            status = m_VideoHandle.SetImageSize(s32VideoID, mode & (ColorMode)(-16385), size.Width, size.Height);
            int s32Quality = ((m_s32VideoQuality != 0) ? m_s32VideoQuality : 75);
            m_VideoHandle.SetQuality(s32VideoID, s32Quality);
            status = m_VideoHandle.Open(s32VideoID, strFileName);
            double f64Value = 0.0;
            if (m_f64VideoFrameRate == 0.0)
            {
                new Timing(m_CamParent).Framerate.Get(out f64Value);
            }
            else
            {
                f64Value = m_f64VideoFrameRate;
            }

            status = m_VideoHandle.SetFramerate(s32VideoID, f64Value);
            status = m_VideoHandle.Start(s32VideoID);
            if (status == Status.Success)
            {
                m_CamParent.EventFrame += onSaveFrame;
                m_bRunning = true;
            }
        }
        else
        {
            status = Status.NoSuccess;
        }

        return status;
    }

The DLL import definition:

[DllImport("uEye_tools", CallingConvention = CallingConvention.Cdecl, EntryPoint = "isavi_InitAVI")]
        public unsafe static extern int InitAviX86(int* s32ID, int hCam);

The function:

public unsafe Status Init(Camera camera, out int s32VideoID)
    {
        Status status = Status.Success;
        s32VideoID = 0;
        camera.GetHandle(out var camHandle);
        int num = 0;
        try
        {
            fixed (int* s32ID = &s32VideoID)
            {
                num = ((IntPtr.Size != 4) ? ToolsWrapper.InitAviX64(s32ID, camHandle) : ToolsWrapper.InitAviX86(s32ID, camHandle));
                status = (Status)num;
                if (status == Status.Success)
                {
                    m_bDllFound = true;
                    return status;
                }

                return status;
            }
        }
        catch (DllNotFoundException)
        {
            return Status.NoSuccess;
        }
    }
  • When you get an unbalanced stack, it may be because you have the wrong call signature, but it's often because you have the wrong calling convention. This might help https://learn.microsoft.com/en-us/dotnet/framework/debug-trace-profile/pinvokestackimbalance-mda – Flydog57 Jul 10 '23 at 01:07
  • I read the link you posted. Thank you. I think it's wrong calling convention. The signature is correct. I can't still figure out how to do the calling convention. – user3281491 Jul 10 '23 at 01:22
  • Please show the `DllImport` definitions, as well as the C function declarations. If it's a COM library, please show the COM wrapper class definition. – Charlieface Jul 10 '23 at 01:22
  • [DllImport("uEye_tools", CallingConvention = CallingConvention.Cdecl, EntryPoint = "isavi_InitAVI")] public unsafe static extern int InitAviX86(int* s32ID, int hCam); – user3281491 Jul 10 '23 at 01:46
  • @Charlieface Please check the post update. – user3281491 Jul 10 '23 at 01:59
  • And how is `InitAviX86` declared in native C? A quick googling indicates `hCam` parameter is a handle, so it's probably supposed to be `IntPtr` – Charlieface Jul 10 '23 at 02:28
  • INT isavi_InitAVI (INT* pnAviID, HIDS hCam) https://www.1stvision.com/cameras/IDS/IDS-manuals/uEye_Manual/isavi_initavi.html – user3281491 Jul 10 '23 at 13:37

0 Answers0