我可以获得指向 Span 的指针吗?
Can I get a pointer to a Span?
我有一个(ReadOnly)Span<byte>
,我想从中解码一个字符串。
只有在 .NET Core 2.1 中,我才有新的重载来从中解码字符串而无需复制字节:
Encoding.GetString(ReadOnlySpan<byte> bytes);
在 .NET Standard 2.0 和 .NET 4.6(我也想支持)中,我只有经典重载:
Encoding.GetString(byte[] bytes);
Encoding.GetString(byte* bytes, int byteCount);
第一个需要将字节复制到我想避免的数组中。
第二个需要一个字节指针,所以我考虑从我的跨度中获取一个,比如
Encoding.GetString(Unsafe.GetPointer<byte>(span.Slice(100)))
...但我没能找到真正的方法。我尝试了 void* Unsafe.AsPointer<T>(ref T value)
,但我无法将跨度传递给它,也没有找到另一种处理指针(和跨度)的方法。
这是否可能,如果可能,如何实现?
试试这个:
Span<byte> bytes = ...;
string s = Encoding.UTF8.GetString((byte*)Unsafe.AsPointer(ref bytes.GetPinnableReference()),
bytes.Length);
如果您使用的是 C# 7.3 或更高版本,则可以使用对 fixed
语句的扩展,该语句可以在类型上使用任何适当的 GetPinnableReference
方法(Span
和 ReadOnlySpan
有):
fixed (byte* bp = bytes) {
...
}
当我们处理指针时,这当然需要 unsafe
上下文。
C# 7.0 到 7.2 没有这个,但允许以下内容:
fixed (byte* bp = &bytes.GetPinnableReference()) {
...
}
我有一个(ReadOnly)Span<byte>
,我想从中解码一个字符串。
只有在 .NET Core 2.1 中,我才有新的重载来从中解码字符串而无需复制字节:
Encoding.GetString(ReadOnlySpan<byte> bytes);
在 .NET Standard 2.0 和 .NET 4.6(我也想支持)中,我只有经典重载:
Encoding.GetString(byte[] bytes);
Encoding.GetString(byte* bytes, int byteCount);
第一个需要将字节复制到我想避免的数组中。
第二个需要一个字节指针,所以我考虑从我的跨度中获取一个,比如
Encoding.GetString(Unsafe.GetPointer<byte>(span.Slice(100)))
...但我没能找到真正的方法。我尝试了 void* Unsafe.AsPointer<T>(ref T value)
,但我无法将跨度传递给它,也没有找到另一种处理指针(和跨度)的方法。
这是否可能,如果可能,如何实现?
试试这个:
Span<byte> bytes = ...;
string s = Encoding.UTF8.GetString((byte*)Unsafe.AsPointer(ref bytes.GetPinnableReference()),
bytes.Length);
如果您使用的是 C# 7.3 或更高版本,则可以使用对 fixed
语句的扩展,该语句可以在类型上使用任何适当的 GetPinnableReference
方法(Span
和 ReadOnlySpan
有):
fixed (byte* bp = bytes) {
...
}
当我们处理指针时,这当然需要 unsafe
上下文。
C# 7.0 到 7.2 没有这个,但允许以下内容:
fixed (byte* bp = &bytes.GetPinnableReference()) {
...
}