5

Is it possible to create a struct from a Memory<byte> without copying to an array? Or better yet, create a struct and a Memory<byte> that share the same managed memory?

Reading a C/C++ data structure in C# from a byte array is tantalizingly close but not quite applicable. Memory<T> has a Pin method, but it returns a MemoryHandle instead of a GCHandle.

XY: I'm reading and writing Memory<byte> from a socket, using BinaryPrimitives on spans obtained from slices to get and set individual fields. Representing the Memory as a struct would be nicer.

S.S. Anne
  • 15,171
  • 8
  • 38
  • 76
StackOverthrow
  • 1,158
  • 11
  • 23
  • You can use `MemoryMarshall.Cast` to convert a `Span` to a `Span` without copying bytes - at least, I think that is the (very poorly documented) syntax now. – NetMage Aug 06 '19 at 22:42
  • Manual manipulation of memory is exceedingly unusual in C#. You typically avoid it as much as possible, and when a particular interface forces you to use it, you immediately covert it into more typical data types to work with. It appears you are violating these norms, but your justification for doing so is poorly explained. In particular, I don't understand why you don't just write some `byte[]` directly to the socket instead of manipulating memory. It's also not clear that you're actually doing the conversions I mentioned, which leaves one wondering if C# is a good language for your problem. – jpmc26 Sep 11 '19 at 01:01
  • 1
    @jpmc26 I'm not sure it's so unusual. The .NET Core developers evidently decided that the preferred way to work with `SocketAsyncEventArgs` is to use a `Memory` instead of a `byte[]` as the buffer. The API discussed [here](https://github.com/dotnet/corefx/issues/17281) exists in 2.2, although it's not documented. In fact, several of the undocumented overloads of `SetBuffer` convert their argument to a `Memory` and set the `MemoryBuffer` property instead of the old `Buffer` property. – StackOverthrow Sep 16 '19 at 17:33
  • @jpmc26 In general, `Memory` and `Span` are *much* nicer to work with. The entire standard API seems to be moving toward preferring them over `byte[]`. It's just the documentation that's not keeping up. – StackOverthrow Sep 16 '19 at 17:37

1 Answers1

6

.Net Core / .Net Standard 2.1 supports MemoryMarshal.Cast<TFrom, TTo> to do a reinterpret cast on a Span<TFrom> to a Span<TTo>. You should be able to use the Memory<T>.Span property to get a Span and then convert it to your struct.

NetMage
  • 26,163
  • 3
  • 34
  • 55