memcmp (msvcrt)
Last changed: -90.212.65.35

.
Summary
Very fast comparison of byte arrays.

C# Signature (x86 and x64):

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

C# Signature (x64 only):

[DllImport("msvcrt.dll")]
static extern int memcmp(IntPtr ptr1, IntPtr ptr2, int count);

C# Unsafe Signature (x64 only):

[DllImport("msvcrt.dll")]
static extern unsafe int memcmp(void* ptr1, void* ptr2, int count);

Alternative Managed API:

Enumerable.SequenceEqual see: http://msdn.microsoft.com/en-us/library/system.linq.enumerable.sequenceequal.aspx

Notes:

WARNING
using the the x64 only signtaures on an x86 machine will result in a PInvoke stack imbalance. For x86 and x64 platform compatibility make sure to use a signature which specifies the Cdecl calling convention and uses the UIntPtr type to correctly marshall the size_t count argument.

Tips & Tricks:

When calling memcmp via pinvoke there is no need to use unsafe code or pinning because the framework will automatically pin the arrays for you.

Sample Code:

Example 1 (x86 and x64):

public static class ByteArrayExtensions
{
   [DllImport("msvcrt.dll", CallingConvention=CallingConvention.Cdecl)]
   private static extern int memcmp(byte[] b1, byte[] b2, UIntPtr count);

   public static bool SequenceEqual(this byte[] b1, byte[] b2)
   {
      if (b1 == b2) return true;

      if (b1 == null || b2 == null || b1.Length != b2.Length) return false;

      return memcmp(b1, b2, new UIntPtr((uint)b1.Length)) == 0;
   }
}

Example 2 (x64 only):

//http://www.cplusplus.com/reference/clibrary/cstring/memcmp/
unsafe bool CompareByteArray(byte[] b1, byte[] b2)
{
     fixed (byte* p1 = b1)
     fixed (byte* p2 = b2)
     {
        return memcmp((void*)p1, (void*)p2, b1.Length) == 0;
     }
}

Edits:

Added (x86 and x64) signature and example.
Removed SetLastError attribute from bottom 2 signatures as memset does not use this API.

Documentation
memcmp on MSDN