0

As a corollary to Need C# JSImport async signature interop example to match async Javascript method - Blazor

I'd like to find a Span/ArraySegment solution to passing and receiving parameters via javascript interop in Blazor.

Here's my best attempt so far, with syntax I would expect to work:

The import

[JSImport("getMessage", "SampleJS")]
[return: JSMarshalAs<JSType.Promise<JSType.Any>>()]
internal static partial Task<object> 
  GetWelcomeMessage([JSMarshalAs<JSType.MemoryView>] ArraySegment<byte> bytes);

JS module

export async function getMessage(dataPointer) {
  var maskedData = new Uint8Array(dataPointer)  // this just creates a zero-filled array
  console.log(maskedData)
  return await new Promise((resolve) => {
    setTimeout(() => {
      resolve(maskedData);
    }, 2000);
  });
}

This just logs the data (bytes) received, waits 2s and returns the same data.

Usage

byte[] sampleData = Encoding.UTF8.GetBytes("Hello from C#");
ArraySegment<byte> sampleDataPointer = new ArraySegment<byte>(sampleData);
object? result = await GetWelcomeMessage(sampleDataPointer);
if (result is byte[] bytes)
{
    message = Encoding.UTF8.GetString(bytes);
    Console.WriteLine($"Got {message} from {result.GetType()}");
}

So the problem is in the javascript method. I can't turn the javascript's incoming MemoryView parameter into a Uint8Array so I can work with it. Any suggestions?

Many thanks to Mister Magoo for getting this off the ground

Sean
  • 2,531
  • 2
  • 17
  • 17

1 Answers1

2

Here is the API of IMemoryView https://github.com/dotnet/runtime/blob/1631f312c6776c9e1d6aff0f13b3806f32bf250c/src/mono/wasm/runtime/dotnet.d.ts#L246-L264

The marshaler would GC pin it for you in case of ArraySegment but not for Span.

EDIT BELOW is from original poster so this answer gets the credit:

This answer eventually lead me to the solution. My sample code works if you modify the javascript line from

var maskedData = new Uint8Array(dataPointer)

to

var maskedData = new Uint8Array(dataPointer.slice())

Many thanks!

Sean
  • 2,531
  • 2
  • 17
  • 17
Pavel Savara
  • 3,427
  • 1
  • 30
  • 35