Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

How to use the new Span API on the C# project #8084

Closed
felipejfc opened this issue Nov 23, 2020 · 4 comments
Closed

How to use the new Span API on the C# project #8084

felipejfc opened this issue Nov 23, 2020 · 4 comments
Assignees
Labels

Comments

@felipejfc
Copy link

felipejfc commented Nov 23, 2020

I'm trying to do the following:

I have a C# application that uses a C shared library and does a pinvoke to this C lib, it then receives a IntPtr pointing to data allocated in C side containing a protobuf message.

I'm trying to build this message on C# side by using Message.MergeFrom() on the C# side but without allocating new memory, just accessing directly the unmanaged memory from C side.

I thought this would be possible now since #5888 but I'm having a hard time trying to figure out how.

Any help?

Best!

@jskeet
Copy link
Contributor

jskeet commented Nov 25, 2020

Removed assignment from myself - I haven't looked at the Span API in detail with protobuf and don't have time to take on work outside my main projects right now.

@jtattermusch
Copy link
Contributor

Note that general usage questions shouldn't be posted here, just actual issues.

Nevertheless: to parse from unmanaged memory, what you want to do is to first create a Span from the unmanaged pointer to the data. (That needs to be done under unsafe block). After that you can just call,
e.g. YourMessage.Parser.ParseFrom(ReadOnlySequence<byte> data). A read only sequence can be created allocation-free from a Span.

FTR the API was added here: #7351

@felipejfc
Copy link
Author

Sorry and thanks @jtattermusch. Can you say how do I create the ReadOnlySequence from the Span? I can't find any method for doing so...

I'm trying like:

Span<byte> data = new Span...
Protos.Request.Parser.ParseFrom(new ReadOnlySequence<byte>(data));

But this isn't allowed: Argument 1: cannot convert from 'System.Span' to 'System.ReadOnlyMemory' csharp(CS1503)

@jtattermusch
Copy link
Contributor

Sorry and thanks @jtattermusch. Can you say how do I create the ReadOnlySequence from the Span? I can't find any method for doing so...

I'm trying like:

Span<byte> data = new Span...
Protos.Request.Parser.ParseFrom(new ReadOnlySequence<byte>(data));

But this isn't allowed: Argument 1: cannot convert from 'System.Span' to 'System.ReadOnlyMemory' csharp(CS1503)

Sorry, I spoke too soon.

Yes, you need to create a ReadOnlyMemory from an unmanaged pointer (as ReadOnlySequence doesn't take Span).
That's done by subclassing a MemoryManager:
https://docs.microsoft.com/en-us/dotnet/api/system.buffers.memorymanager-1?view=net-5.0

Examples:

private sealed unsafe class UnmanagedMemoryManager<T> : MemoryManager<T> where T : unmanaged

https://github.com/grpc/grpc/blob/a1ad4800da2bb02c843bdaea8fb06518916b6fba/src/csharp/Grpc.Core/Internal/SliceMemoryManager.cs#L32

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

4 participants