Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Using pointer to array in unsafe C#

Tags:

c#

unsafe

In C, I can define a pointer to an array like this:

char b1[SOME_SIZE];
char (*b3)[3]=(char(*)[3])b1;

so that b3[i][j] == b1[i*3+j].

Can I declare such a pointer, b3, in unsafe C#?

My intention is to access bitmap channels as:

///...
unsafe {
    //...
    byte *target; //8bpp
    byte (*source)[3]; //24bpp
    //...
    target[x]=(source[x][0]+source[x][1]+source[x][2])/3;
    //...

I hope this way, using source[x][ch] instead of source[x*3+ch] to get some compiler optimization.

like image 624
LS_ᴅᴇᴠ Avatar asked Dec 11 '13 10:12

LS_ᴅᴇᴠ


People also ask

Why are pointers considered unsafe?

Because pointers provide access a memory location and because data and executable code exist in memory together, misuses of pointers can lead to both bizarre effects and very subtle errors. dangling pointers.

What are unsafe pointers?

An unsafe pointer type is provided for compatibility with C and to implement dynamic, aliasing data struc- tures (for example linked lists). This is not the default pointer type and the onus is on the programmer to ensure memory safety for these types. An unsafe pointer is opaque unless accessed in an unsafe region.

Which is the operator that Cannot operate on pointers in an unsafe context?

The void* type represents a pointer to an unknown type. Because the referent type is unknown, the indirection operator cannot be applied to a pointer of type void* , nor can any arithmetic be performed on such a pointer.

Which type is used in unsafe mode?

Now to understand what UnsafeMode is. Unsafe is a C# programming language keyword to denote a section of code that is not managed by the Common Language Runtime (CLR) of the . NET Framework, or unmanaged code. Unsafe is used in the declaration of a type or member or to specify a block code.


1 Answers

[StructLayout(LayoutKind.Sequential, Pack = 1)]
struct FastPixel
{
    public readonly byte R;
    public readonly byte G;
    public readonly byte B;
}


private static void Main()
{
    unsafe
    {
        // 8-bit.
        byte[] b1 =
        {
            0x1, 0x2, 0x3,
            0x6, 0x7, 0x8,
            0x12, 0x13, 0x14
        };


        fixed (byte* buffer = b1)
        {
            var fastPixel = (FastPixel*) buffer;
            var pixelSize = Marshal.SizeOf(typeof (FastPixel));

            var bufferLength = b1.Length / pixelSize;
            for (var i = 0; i < bufferLength; i++)
            {
                Console.WriteLine("AVERAGE {0}", (fastPixel[i].R + fastPixel[i].G + fastPixel[i].B)/pixelSize);
            }
        }
    }
}

}

This should be pretty much identical what you have. Note that I don't expect any performance gains. This is not micro-optimization, it's nano-optimization.

If dealing with huge images, look into parallel programming & SSE and how cache lines work(they have saved me actually 3-4 seconds - crazy right?!)

like image 166
Erti-Chris Eelmaa Avatar answered Sep 30 '22 08:09

Erti-Chris Eelmaa