Skip to content
This repository has been archived by the owner on Mar 28, 2024. It is now read-only.

C#-only way to declare wasm imports and exports #30

Open
SteveSandersonMS opened this issue Jul 29, 2022 · 10 comments
Open

C#-only way to declare wasm imports and exports #30

SteveSandersonMS opened this issue Jul 29, 2022 · 10 comments

Comments

@SteveSandersonMS
Copy link
Owner

Currently to declare a custom WebAssembly import or export you have to write C code, e.g., https://github.com/SteveSandersonMS/dotnet-wasi-sdk/blob/main/src/Wasi.AspNetCore.Server.CustomHost/native/server_interop.c#L7-L17

We should make it possible to declare such imports/exports using just C# only without any native code.

At a basic level this could be achieved fairly easily by codegenerating the equivalent C code that uses the Mono embedding APIs to invoke C#. However going further, we'd want to be able to receive and return nontrivial types, which probably involves a C# sourcegenerator for WIT.

@inkeliz
Copy link

inkeliz commented Aug 4, 2022

There's any simpler example of how use export/import, when using the C?

@SteveSandersonMS
Copy link
Owner Author

SteveSandersonMS commented Aug 5, 2022

No, https://github.com/SteveSandersonMS/dotnet-wasi-sdk/blob/main/src/Wasi.AspNetCore.Server.CustomHost/native/server_interop.c is about as simple as it gets. That's why we should make a simpler mechanism with C# only.

@inkeliz
Copy link

inkeliz commented Aug 5, 2022

I understand the motivation to add C#-only. I'm trying to figure out how server_interop.c works.

Just to make sure, I need to have the Mono toolchain and compile the my_interop.c? The README mention that "You can optionally include other native sources such as .c files in the compilation.", but I'm struggling to understand how to make my C code interact with Mono and get compiled. 🧐

@SteveSandersonMS
Copy link
Owner Author

No, you don't need Mono. No other build tools are needed. Just reference your .c file with WasiNativeFileReference like the Wasi.AspNetCore.Server.CustomHost project does, and it will be included in the compilation.

@flavio
Copy link

flavio commented Aug 8, 2022

There's any simpler example of how use export/import, when using the C?

@inkeliz: you might want to take a look at https://github.com/flavio/wapc-guest-dotnet/blob/main/src/WapcGuest/native/wapc_ffi.c
This is a smaller example.

I hope that helps!

@inkeliz
Copy link

inkeliz commented Aug 8, 2022

Thank you, @flavio. I think that will be very useful for any future readers. My primary concern was how to compile that, since I'm not familiar with C#/Dotnet, so I'm not sure how things are suppose to compile. 😅

I manage to use force the compilation including the WasiNativeFileReference, as @SteveSandersonMS said. However, I need to include that into the .csproj directly. I'm not sure why the build folder doesn't work, where is the result. Since that is just for testing, not a library, I think it's fine.

@SteveSandersonMS
Copy link
Owner Author

I need to include that into the .csproj directly

Good, that's the right thing to do if you're just testing! Having .props/.targets files that get bundled into a NuGet package is only for people shipping NuGet packages - it's nothing specific to dotnet-wasi-sdk but more of a general NuGet/MSBuild pattern.

@ChristianWeyer
Copy link

@ghost
Copy link

ghost commented May 16, 2023

``Hello, i do have an unresolved doubt:
is there a way, when for example compiling with wasi a classlib (.dll), to mark as exported the methods i want and use those methods importing the .wasm file in an application via wasmtime for example?

I tried, for ease of testing, to build a classlib with a generic method

namespace wasmlibrary;
public static class Class1
{
    public static int method(int i)
    {
        return i++;
    }
}

and in another console project use wasmtime.net to load the module


 using (var engine = new Engine())
        using (var store = new Store(engine))
        using (var linker = new Linker(engine))
        using (var module = Module.FromFile(engine, "../../../../wasmlibrary/bin/Debug/net7.0/wasmlibrary.wasm"))
        {
            linker.DefineWasi();  
            dynamic instance = linker.Instantiate(store, module);
            var run = instance.GetFunction<int, int>("method");
        }

but, debugging, module only exports the basic methods (malloc, free, _run, etc..), and run is null, meaning that the method is not exported.

thanks to everyone in advance!

@iwate
Copy link

iwate commented Nov 12, 2023

I tried exporting wasi-wasm function by using ILCompiler.LLVM. And it worked.

https://github.com/iwate/learn-wasm-with-dotnet/tree/main/challenge09/wasilib

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

No branches or pull requests

5 participants