gpt4 book ai didi

c# 无需复制和迭代即可将数组类型转换为另一种数组类型

转载 作者:行者123 更新时间:2023-12-01 23:27:26 25 4
gpt4 key购买 nike

我正在尝试将存储为 uint[] 的 UTF-32 编码字符串解码为 string 类型。

为此,我想使用 System.Text.Encoding.UTF32.GetString 方法。但是,此函数的重载采用 Byte[]Byte*。我不介意在这种特殊情况下使用不安全(但是来自 C,我不知道这样做的后果)

我找到了一种方法,可以直接或间接地将整个数组复制到另一个类型为 byte[] 的数组。在这个问题中,我只想知道是否可以将 uint[] 转换为 byte[](或转换为 byte*,如果无法转换为 byte[]) 不复制

最佳答案

如果可能,您应该绝对在 canton7 的同一问题上使用跨度方法,here .

这个回答只是为了补充问题中的一些信息,具体来说:

I don't mind using unsafe in this particular case (however coming from C, I am not aware of the consequences of doing so)

此信息相关的主要时间是:

  • spans 在您的目标平台中不可用(或者不能与您使用的 API 一起使用)
  • 您正在通过 P/Invoke 与非托管库对话

只是添加一些术语:byte*是一个非托管指针(“不安全”),并且ref byte是一个托管指针(“安全”,相对而言)。跨度基本上是“托管指针加上长度”;所以:Span<byte> (或 ReadOnlySpan<byte> )与一对 byte* 大致相当(在未管理的土地上)和 int (长度)。巨大的区别在于垃圾收集器理解托管指针(包括跟踪它们接触的内容,并在决定移动内存时修复它们),并且甚至不看 非托管 指针(它们只是不透明的 native 整数)- 因此:让所有内容都托管 可以避免很多问题。

因此,如果您获得指向数据的非托管指针,您的工作就是确保数据在您访问时不会被移动使用它,这会使您的指针无效。为此,您通常使用 fixed关键字,即(在 unsafe block 中):

uint[] data = ...
fixed (uint* u32ptr = data)
{
// we can coerce pointers:
byte* bptr = (byte*)u32ptr;

// TODO: and now we can use that byte* (along with data.Length * sizeof(uint))
// to pass to e.g. Encoding methods
return Encoding.UTF32.GetString(bptr, data.Length * sizeof(uint));
}

重要的是不要以可以转义 u32ptr 的方式存储这样的指针(此处为 bptrfixed)堵塞。例如,将其存储在田野上。只要您不这样做,就没问题:垃圾收集器知道如何解释 fixed ,并且知道它不能移动 data当线程在该区域内时; fixed是一种成本非常低的临时固定数据的方法。有一种第二种方式,用于更长时间运行的需求 - 通常是因为您将托管内存交给一个非托管 API,该 API 然后保存指针作为字段比您可能在 fixed 中使用的 P/Invoke 调用更长区域 - GCHandle类型为 GCHandleType.Pinned - 但通常应避免这种情况。

关于c# 无需复制和迭代即可将数组类型转换为另一种数组类型,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/66982555/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com