tags:

views:

79

answers:

1

My unsafe method accepts a collection byte[]s. All of these byte[]s are of the same size.

I need to iterate over them all, searching for certain patterns. The search is inherently reinterpret-cast style: at each offset, I need to consider a value as if it were a float, a double, a short, an int, etc. So getting a byte* for each input byte[] and incrementing it on each iteration seems like a natural approach.

Unfortunately I can't find any way to create a collection of byte* - or, more specifically, to initialize it from a collection of arrays. Any ideas?

Here's a somewhat contrived version of the task:

static unsafe void SearchIteration(List<byte[]> arrays, byte[] resultArr)
{
    fixed (byte* resultFix = resultArr)
    {
        byte* resultPtr = resultFix;
        byte*[] pointers = new byte*[arrays.Count];

        <some code to fix all the arrays and store the pointers in "pointers">

        int remaining = resultArr.Length;
        while (remaining > 0)
        {
            <look at resultPtr and each of the pointers and update *resultPtr>

            remaining--;
            for (int i = 0; i < pointers.Length; i++)
                pointers[i]++;
        }
    }
}

Essentially the question is how to initialize pointers with the addresses of arrays, while pinning the arrays so that GC doesn't move them.

+1  A: 

use GCHandle.Alloc() from System.Runtime.InteropServices:

var handles = new GCHandle[arrays.Count];
byte*[] pointers = new byte*[arrays.Count];
for(int i = 0; i < arrays.Count; ++i)
{
    handles[i] = GCHandle.Alloc(arrays[i], GCHandleType.Pinned);
    pointers[i] = (byte*)handles[i].AddrOfPinnedObject();
}
try
{
    /* process pointers */
}
finally
{
    for(int i = 0; i < arrays.Count; ++i)
    {
        handles[i].Free();
    }
}
max
That pins the objects. But where does the pointer point to (the array content or the CLR object header of the array object)?
dtb
it points to exatly what you are expecting - first array element
max
Thanks max, this works. Forgot to accept earlier.
romkyns