Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

unsigned char * - Equivalent C#

Tags:

c++

c#

I am porting a library from C++ to C# but have come across a scenario I am unsure of how to resolve, which involves casting an unsigned char * to an unsigned int *.

C++

unsigned int c4;
unsigned int c2;
unsigned int h4;

int pos(unsigned char *p)
{
    c4 = *(reinterpret_cast<unsigned int *>(p - 4));
    c2 = *(reinterpret_cast<unsigned short *>(p - 2));
    h4 = ((c4 >> 11) ^ c4) & (N4 - 1);

    if ((tab4[h4][0] != 0) && (tab4[h4][1] == c4))
    {
        c = 256;
        return (tab4[h4][0]);
    }

    c = 257;
    return (tab2[c2]);
}

C# (It's wrong):

 public uint pos(byte p) 
 {
        c4 = (uint)(p - 4);
        c2 = (ushort)(p - 2);
        h4 = ((c4 >> 11) ^ c4) & (1 << 20 - 1);
        if ((tab4[h4, 0] != 0) && (tab4[h4, 1] == c4)) {
            c = 256;
            return (tab4[h4, 0]);
        }
        c = 257;
        return (tab2[c2]);
 }

I believe in the C# example, you could change byte p to byte[] but I am clueless when it would come to casting byte[] to a single uint value.

Additionally, could anyone please explain to me, why would you cast an unsigned char * to a unsigned int *? What purpose does it have?

Any help/push to direction would be very useful.

like image 397
Steve_B19 Avatar asked Sep 05 '26 09:09

Steve_B19


1 Answers

Translation of the problematic lines would be:

int pos(byte[] a, int offset)
{
    // Read the four bytes immediately preceding offset
    c4 = BitConverter.ToUInt32(a, offset - 4);
    // Read the two bytes immediately preceding offset
    c2 = BitConverter.ToUInt16(a, offset - 2);

and change the call from x = pos(&buf[i]) (which even in C++ is the same as x = pos(buf + i)) to

x = pos(buf, i);

An important note is that the existing C++ code is wrong as it violates the strict aliasing rule.

like image 142
Ben Voigt Avatar answered Sep 06 '26 23:09

Ben Voigt