0

I have a C# server which needs to calculate a CRC (CRC16 – CCITT (xModem)) from a byte array. The thing is that I would like to make a call for a C++ code from C#, for performance gain. But I'm struggling to accomplish this task, as the provided C++ algorithm they gave me is apparently not compatible with VC++.

CRC calculation function:

const UINT16 crc_table[16] = {
    0x0000, 0x1021, 0x2042, 0x3063, 0x4084, 0x50a5, 0x60c6, 0x70e7,
    0x8108, 0x9129, 0xa14a, 0xb16b, 0xc18c, 0xd1ad, 0xe1ce, 0xf1ef
};

UINT16 CalculateCrc( UINT8 *data, UINT32 len )
{
    UINT i;
    UINT16 crc = 0;

    while( len-- )
    {
        i = ( crc >> 12 ) ^ ( *data >> 4 );
        crc = crc_table[ i & 0x0F ] ^ ( crc << 4 );
        i = ( crc >> 12 ) ^ ( *data >> 0 );
        crc = crc_table[ i & 0x0F ] ^ ( crc << 4 );
        data++;
    }

    return ( crc & 0xFFFF );
}

where *data is a pointer to a byte[] and len is the length of this byte[];

To be able to "inject" this code onto my C# code I created a C++ Class Library, but I'm uncertain on how to use it after it's finished.

Finally, my questions are:

  • How to port the provided algorithm to work with VC++?
  • How to use the compiled Class Library to actually calculate the code on my C# server?
  • Is this approach (create a C++ code to calculate the CRC) better performance wise?
Bruno Klein
  • 3,217
  • 5
  • 29
  • 39

1 Answers1

2

The Just In Time compiler in CLR is pretty good. I don't think you'll see much of a performance gain by using C++. In fact, it may even be slower because of the extra overhead.

Translating your algorithm from C to C# should be pretty easy; just change the data types to their equivalents and add casts where needed:

ushort[] crc_table = {
    0x0000, 0x1021, 0x2042, 0x3063, 0x4084, 0x50a5, 0x60c6, 0x70e7,
    0x8108, 0x9129, 0xa14a, 0xb16b, 0xc18c, 0xd1ad, 0xe1ce, 0xf1ef
};

ushort CalculateCrc( byte[] data )
{
    int i;
    ushort crc = 0;
    int len = data.Length;

    for (int j = 0; j < len; j++)
    {
        i = ( crc >> 12 ) ^ ( data[j] >> 4 );
        crc = (ushort) (crc_table[ i & 0x0F ] ^ ( crc << 4 ));
        i = ( crc >> 12 ) ^ ( data[j] >> 0 );
        crc = (ushort) (crc_table[ i & 0x0F ] ^ ( crc << 4 ));
    }

    return crc;
}

I haven't tested this, though.

Joni
  • 108,737
  • 14
  • 143
  • 193