Blazor WASM unmarshalled interop with JSImport #54946
-
Hi all, Here is what I have [JSImport("globalThis.test2")]
public static partial void Test2([JSMarshalAs<JSType.Any>] object param);
...
JsUnmarshalled.Test2(new InteropStruct()
{
Name = "Brigadier Alistair Gordon Lethbridge-Stewart",
Year = 1968,
}); JS function test2(flights){
console.log(flights);
const name = Blazor.platform.readStringField(flights, 0);
const year = Blazor.platform.readInt32Field(flights, 8);
console.log(`${name} (${year})`)
} But I'm getting null when reading I tried another way [JSImport("globalThis.test2")]
public static partial void Test([JSMarshalAs<JSType.Number>] int param); and call it like this: var a = new InteropStruct()
{
Name = "Brigadier Alistair Gordon Lethbridge-Stewart",
Year = 1968,
};
IntPtr tr = (int)&a;
JsUnmarshalled.Test(tr.ToInt32()); That worked. But I'm pretty sure that's not how it's supposed to be used. On the other hand the function I wan to call is supposed to decode fields from my managed .net object, copy then, and create JS objects to be used in JS. The function would be synchronous. If I'm not mistaken I don't really need to worry about GC moving my object somewhere else since GC can only do that after my JS function completes. I know that's a niche usecase but maybe someone has some ideas on how to do this correctly? The struct for completness [StructLayout(LayoutKind.Explicit)]
public struct InteropStruct
{
[FieldOffset(0)]
public string Name;
[FieldOffset(8)]
public int Year;
} |
Beta Was this translation helpful? Give feedback.
Replies: 3 comments 17 replies
-
cc @pavelsavara |
Beta Was this translation helpful? Give feedback.
-
At the moment we don't support marshaling structures with The You said that you have lot of data.
Hope this helps. |
Beta Was this translation helpful? Give feedback.
-
Except this unsafe interop is exactly what you use for RenderTreeFrame's is it not? Y'all aren't the only ones who know how to pointer arithmetic. ;) I was extensively using the low level interop - in both directions - in order to achieve performance that was not possible with normal Blazor. I understood these were "internal" APIs, but I expected they might change - not be eliminated. Despite the Mono WASM SDK ostensibly still supporting this, as far as I can tell you obfuscated away any ability for us to use these. For example |
Beta Was this translation helpful? Give feedback.
At the moment we don't support marshaling structures with
[JSImport]
.The
[JSMarshalAs<JSType.Any>]
will marshal it as a proxy JS objects, just a wrapper aroundGCHandle
.That's why Blazor's deprecated unsafe pointer based
platform.readStringField
would not work on it.We deprecated this because it was really unsafe, because GC could move the managed objects in memory.
You said that you have lot of data.
Possible solutions how you can transfer it:
void Method(string name, int year)
InteropStruct[]
you can transform it into multiple arrays of simple types. And then marshal it asvoid …