I'm trying to create a Managed Array of doubles from an array of bytes. I have the problem working currently, but I wanted to optimize. Here's some code that I would like to work:
private unsafe static double[] _Get_Doubles(byte[] _raw_data)
{
double[] ret;
fixed (byte* _pd = _raw_data)
{
double* _pret = (double*)_pd;
ret = (double[])*_pret; //FAILURE
}
}
Please let me know how to cope with these problems.
-Aaron
One of the key things to notice about the code you have posted is that there is no way to know how many items are pointed to by the return value, and a managed array needs to know how big it is. You can return a double*
or create a new double[XXX]
and copy the values or even (if the count is constant) create a struct
with a public fixed double _data[2];
member and cast the raw data to that type.
Just now, I thought that stackalloc
would be the right way, but it fails. Most importantly, I now know that it was doomed to fail. There is no way to do what I want to do.
This can be seen by restating the question:
How can I create a managed array around an 'unsafe' array?
Since a managed array has header information (because it's a class around a chuck of memory), it requires more space in memory than the array itself. So, the answer is:
Allocate space before (and/or after? depending on the way managed arrays are stored in memory) the array itself and put the managed information (length, (et cetera)) around the 'unsafe' array.
This is not easily possible because to guarantee that there is data enough around the array is shaky at best. In my particular example there may be enough space for it because a managed byte[] is passed in meaning that there is data around the array, but to assert that the same data is appropriate for managed double[] is dubious at best, but most likely erroneous, and to change the data to make it appropriate for managed double[] is nefarious.
[EDIT]
It looks like Marshal.Copy
is the way to go here. Create a new array and let Marshal copy them (hoping that he will be quicker than me, or that perhaps at some later date, he will be quicker):
var ret = new double[_raw_data.Length / sizeof(double)];
System.Runtime.InteropServices.Marshal.Copy(new System.IntPtr(_pret), ret, 0, ret.Length);
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With