dotnet / runtime

.NET is a cross-platform runtime for cloud, mobile, desktop, and IoT apps.
https://docs.microsoft.com/dotnet/core/
MIT License
14.91k stars 4.64k forks source link

Blazor wasm dynamic linking native sidemodules #75257

Open Hazardu opened 2 years ago

Hazardu commented 2 years ago

Is there an existing issue for this?

Is your feature request related to a problem? Please describe the problem.

I am trying to link a C++ library compiled with Emscripten to a Blazor wasm application, and use pinvoke. Thus far, the only way to link the two is to use static linking via NativeFileReference, but emcc contains functionality to dynamically link side modules and a main module.

Comparing the generated JS in an app where both the lib and main app are written in C++ to one with Blazor Wasm and NativeFileReference, it seems that the code responsible for loading the functions into the Module object is missing, thus when the app tries to call them when they are uninitialized and abort is called and the whole thing breaks.

Trying a different approach of statically linking a part of the C++ code containing C wrapper functions that are PInvoked and dynamically linking the C++ class that is wrapped, the same issue happened after the C function reached a function call.

Describe the solution you'd like

NativeFileReference other than accepting relocatable wasm files for static linking, would accept native libs compiled with Emscripten's SIDE_MODULE flag and expand the generated javascript to load them at loadtime.

Additional context

https://github.com/Devsh-Graphics-Programming/GPU-With-C-Sharp-Angular-WASM Thus far this app is on the small end, but we are considering making a robust native wasm library that contains the Nabla engine. For that dynamic linking is preferable.

Emscripten doc https://emscripten.org/docs/compiling/Dynamic-Linking.html

dotnet-issue-labeler[bot] commented 2 years ago

I couldn't figure out the best area label to add to this issue. If you have write-permissions please help me learn by adding exactly one area label.

ghost commented 2 years ago

Tagging subscribers to 'arch-wasm': @lewing See info in area-owners.md if you want to be subscribed.

Issue Details
### Is there an existing issue for this? - [X] I have searched the existing issues ### Is your feature request related to a problem? Please describe the problem. I am trying to link a C++ library compiled with Emscripten to a Blazor wasm application, and use pinvoke. Thus far, the only way to link the two is to use static linking via `NativeFileReference`, but emcc contains functionality to dynamically link side modules and a main module. Comparing the generated JS in an app where both the lib and main app are written in C++ to one with Blazor Wasm and `NativeFileReference`, it seems that the code responsible for loading the functions into the `Module` object is missing, thus when the app tries to call them when they are uninitialized ad `abort` is called and the whole thing breaks. Trying a different approach of statically linking a part of the C++ code containing C wrapper functions that are PInvoked and dynamically linking the C++ class that is wrapped, the same issue happened after the C function reached a function call. ### Describe the solution you'd like `NativeFileReference` other than accepting relocatable wasm files for static linking, would accept native libs compiled with Emscripten's SIDE_MODULE flag and expand the generated javascript to load them at loadtime. ### Additional context https://github.com/Devsh-Graphics-Programming/GPU-With-C-Sharp-Angular-WASM Thus far this app is on the small end, but we are considering making a robust native wasm library that contains the Nabla engine. For that dynamic linking is preferable.
Author: Hazardu
Assignees: -
Labels: `arch-wasm`, `untriaged`
Milestone: -
radical commented 2 years ago

cc @radekdoulik @pavelsavara @SteveSandersonMS @kg

BenMcLean commented 3 months ago

I could be wrong here but it looks like this is the primary issue blocking Godot 4 and Stride and MonoGame and probably most / any other FOSS game engines / frameworks that support scripting in C# from building programs for WebAssembly on .NET Core 5+. It would be nice for it to get more attention.

GeorgeS2019 commented 3 months ago

@BenMcLean

this is the primary issue blocking Godot 4 from building programs for WebAssembly on .NET Core 5+.

Will godot-dotnet helps to resolve this?

BenMcLean commented 3 months ago

@BenMcLean

this is the primary issue blocking Godot 4 from building programs for WebAssembly on .NET Core 5+.

Will godot-dotnet helps to resolve this?

Possibly. I'm not sure the Godot team would accept such a PR as I don't think embedding Godot as a library is something they even want to support, but if they will then that would be great.

GeorgeS2019 commented 3 months ago

@BenMcLean https://chat.godotengine.org/channel/dotnet?msg=ow94ZyspFmyvvzGYh

There's also ongoing work on the .NET runtime to use a new NativeAOT-LLVM runtime for the web platform which may solve our problem, but it's very early and very experimental. Not sure how much of this will make it to .NET 9.0.

Anyone can share links to NativeAOT-LLVM?

Found

https://github.com/dotnet/runtimelab/tree/feature/NativeAOT-LLVM

https://learn.microsoft.com/en-us/dotnet/core/deploying/native-aot/?tabs=net8plus%2Cwindows image

Delsin-Yu commented 3 months ago

@GeorgeS2019

Will godot-dotnet helps to resolve this?

No, It won't.

BenMcLean commented 3 weeks ago

@lewing Why did this get pushed into the indefinite future?

Seems like this one and also https://github.com/dotnet/aspnetcore/issues/17730 are really important.

lewing commented 3 weeks ago

The limitations of emscripten's dynamic linking have made it quite challenging for us to use in practice. Can you explain in more detail what problem you are attempting to solve? We use feedback to help prioritize work.

As for browser-wasm threading it is functional and you can try in out in recent net9.0 previews, but only the runtime side and that will remain experimental in net9. The Blazor front end work as indicated in https://github.com/dotnet/aspnetcore/issues/17730 is part of the planning for net10.

cc @danroth27

BenMcLean commented 3 weeks ago

This comment here offered an explanation of how lack of dynamic linking native sidemodules prevents Godot 4 from supporting WASM export for C# scripted projects: https://github.com/godotengine/godot/issues/70796#issuecomment-1618006609

I believe Stride has a similar issue although I can't find it at the moment.