Search code examples
c#comparememcmp

c# memcmp image compare error


im trying to compare 2 smalls blocks of image using the memcmp method. i saw this answer What is the fastest way I can compare two equal-size bitmaps to determine whether they are identical? and i tried to implement this in my project:

private void Form1_Load(object sender, EventArgs e)
{
    Bitmap prev, curr;

    prev = (Bitmap) Image.FromFile(@"C:\Users\Public\Desktop\b.png");



    curr = (Bitmap)Image.FromFile(@"C:\Users\Public\Desktop\b.png");
    MessageBox.Show(CompareMemCmp(prev, curr).ToString());
}

this is the method-

[DllImport("msvcrt.dll")]
private static extern int memcmp(IntPtr b1, IntPtr b2, long count);

public static bool CompareMemCmp(Bitmap b1, Bitmap b2)
{
    if ((b1 == null) != (b2 == null)) return false;
    if (b1.Size != b2.Size) return false;

    var bd1 = b1.LockBits(new Rectangle(new Point(0, 0), b1.Size), ImageLockMode.ReadOnly, PixelFormat.Format32bppArgb);
    var bd2 = b2.LockBits(new Rectangle(new Point(0, 0), b2.Size), ImageLockMode.ReadOnly, PixelFormat.Format32bppArgb);

    try
    {
        IntPtr bd1scan0 = bd1.Scan0;
        IntPtr bd2scan0 = bd2.Scan0;

        int stride = bd1.Stride;
        int len = stride * b1.Height;

        return memcmp(bd1scan0, bd2scan0, len) == 0;
    }
    finally
    {
        b1.UnlockBits(bd1);
        b2.UnlockBits(bd2);
    }
}

and im getting this error when calling memcmp function

A call to PInvoke function 'WindowsFormsApplication1!WindowsFormsApplication1.Form1::memcmp' 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.

any idea why is that happening? i did all based on that answer.


Solution

  • The correct signature is:

    [DllImport("msvcrt.dll", CallingConvention=CallingConvention.Cdecl)]
    static extern int memcmp(IntPtr b1, IntPtr b2, IntPtr count);
    

    because in C, count is size_t, so it can be 32 or 64 bits depending if the program is running at 32 or 64 bits.

    Then to use it:

    return memcmp(bd1scan0, bd2scan0, (IntPtr)len) == 0;