views:

128

answers:

2

Related Question

In the related question, I was trying to figure out the fastest way. The method I chose in that question has become a bottle neck for me. I am reading some binary data from a file and need to put it into a managed structure definition. No unmanaged code is involved so I'm thinking there is a better way than allocating the GCHandle.

Is there a way to just cast an array of bytes to a structure of the same size?

A: 

I have a method like this:

static public T ReadStructure<T>(byte[] bytes)
    where T : struct
{
    int len = Marshal.SizeOf(typeof(T));
    IntPtr i = Marshal.AllocHGlobal(len);

    try
    {
        Marshal.Copy(bytes, 0, i, len);
        return (T)Marshal.PtrToStructure(i, typeof(T));
    }
    finally
    {
        Marshal.FreeHGlobal(i);
    }
}

Admittedly, it's not very fast--but it doesn't need to be, in my case. Is this your current solution, and you're finding that the alloc/copy/release overhead is too slow?

Ben M
I may try this. The problem is I have to read 254 bytes, check if the first 240 contain a type, and if so move on. With this method, I read the data from the file, copy the first 240 bytes to a ptr, check it, then copy the whole 254 to a ptr. Lots of copying happening.
scottm
Sounds like there are a couple of avenues for optimization. Could you post some code?
Ben M
@Ben, the related question has an example of what I am currently doing.
scottm
Since you're reading from a file, you might consider P/Invoking the Win32 file-access methods; you can allocate a big chunk of memory as an IntPtr, read directly into it and then Marshal directly from it without copying to/from a managed byte[] buffer.
Ben M
I tried this. It seems slightly faster and it definitely uses less memory. I'll see how it goes, thanks
scottm
A: 

You could check out such code:


struct Foo
{
  public int x;
}

public unsafe static void Main()
{
  byte[] x = new byte[] { 1, 1, 0, 0 };
  Foo f;

  fixed (byte* xPtr = x)
  {
    f = *((Fpp*)xPtr);
  }

  Console.WriteLine(f.x);
}

It's definitely very unsafe, ad you could have problems if the structure contains some more complex types.

Ravadre
What are the implications of using this method across 32/64bit boundaries? Is there any way to guarantee exactly similar representations on all machines that might be sharing data stored and read with this method?
Ben M
What is Fpp? When I try a similar declaration using my type, I get "Cannot take the address of, get the size of, or declare a pointer to a managed type"
scottm
I think he meant to write Foo, not Fpp.
Ben M
Yeah, it should be Foo, not Fpp :). As for 32/64bit boundaries - 1. You will have some problems with pointers, 2. By default, structures in c# has a sequential layout, so you should not have big surprises with them. 3. You can use [StructLayout(Explicit)] and arrange it as you like. Btw - this method is not a method I'd use for production code, there are places where it can break.
Ravadre