1

从 Double[] src 到 Byte[] dst 的转换可以在 C# 中通过固定指针有效地完成:

fixed( Double* pSrc = src)
{
  fixed( Byte* pDst = dst)
  {
    Byte* ps = (Byte*)pSrc;
    for (int i=0; i < dstLength; i++)
    {
      *(pDst + i) = *(ps +i);
    }
  }
}

我怎样才能对 List src 做同样的事情?即如何获得指向 List 中包含的数组 Double[] 的固定指针?谢谢。

4

7 回答 7

1

您始终可以使用对象ToArray()上的方法List<Double>来获取Double[].

于 2010-12-09T15:23:36.357 回答
1

不知道你的意图是什么,但我认为......你想要 System.Runtime.Interopservices.Marshal.StructToPtr

于 2010-12-09T15:22:46.563 回答
1

我以前使用过这些辅助方法:

byte[] GetBytesBlock(double[] values)
{
   var result = new byte[values.Length * sizeof(double)];
   Buffer.BlockCopy(values, 0, result, 0, result.Length);
   return result;
}

double[] GetDoublesBlock(byte[] bytes)
{
   var result = new double[bytes.Length / sizeof(double)];
   Buffer.BlockCopy(bytes, 0, result, 0, bytes.Length);
   return result;
}

一个例子:

List<double> myList = new List<double>(){ 1.0, 2.0, 3.0};

//to byte[]
var byteResult = GetBytesBlock(myList.ToArray());

//back to List<double>
var doubleResult = GetDoublesBlock(byteResult).ToList();
于 2012-12-11T23:47:17.483 回答
1

您可以使用反射来获取对 List 实例中私有 T[] _items 字段的引用。

警告:在您的代码片段中,您需要确保 dstLength 是 dst 和 src 字节长度中的最小值,这样您就不会尝试复制比可用字节更多的字节。可能您通过创建与 src 完全匹配所需大小的 dst 来做到这一点,但您的代码段并不清楚。

于 2010-12-09T15:41:55.837 回答
0

使用该List<T>.ToArray()方法并对结果数组进行操作。

于 2010-12-09T15:23:01.667 回答
0

这可能有效,但您将丢失数据 - 数组的内容将是 3 和 34 。

    List<double> list = new List<double>();
    list.Add(Math.PI);
    list.Add(34.22);

    byte[] arr = (from l in list
                  select (byte)l).ToArray<byte>();
于 2010-12-09T17:55:43.863 回答
0

你为什么不像往常一样访问列表?

List<double> list = new List<double>();
list.Add(Math.PI);
list.Add(34.22);

byte[] res = new byte[list.Count * sizeof(double)];

unsafe
{
    fixed (byte* pres = res)
    {
        for (int i = 0; i < list.Count; i++)
        {
            *(((double*)pres) + i) = list[i];
        }
    }
}

我没有彻底测试过它,我很少需要不安全的代码,但它似乎工作正常。

编辑:这是另一个(imo 更可取的)解决方案,没有不安全的代码:

int offset = 0;
for (int i = 0; i < list.Count; i++)
{
    long num = BitConverter.DoubleToInt64Bits(list[i]);

    for (int j = 0; j < 8; j++)
    {
        res[offset++] = (byte)num;
        num >>= 8;
    }
}
于 2010-12-09T16:01:39.057 回答