5 ms·
I now use C# for high-level programming and Zig for low-level. Perfect combination for me.
by superfist 2y ago
I now use C# for high-level programming and Zig for low-level. Perfect combination for me.
- actionfromafar 2y agoMaybe I should write that tutorial on how to use C# for low-level.
- dgellow 2y agoYes please do!
- neonsunset 2y agoHeh, I've been procrastinating on making a blog and writing a blog post on "C# for systems programming". Would be nice to read and provide feedback if someone beats me to it.
- superfist 2y agoIt will not work if you low-level target is rp2040 microcontroller board...
- int_19h 2y agoThere was a port of the .NET Nano Framework for RP2040. But I think the more interesting thing is that if you remove all features in C# that require heap allocations, the resulting subset is basically C with namespaces and generics, which is still useful, and certainly possible to compile efficiently even for very constrained platforms.
- superfist 2y agoYes, it's technically doable, but what’s the point of using it if you lose almost the entire standard library because it relies on the GC?
- neonsunset 2y agoThere is a practical answer to this question: https://github.com/bflattened/bflat https://github.com/bflattened/bflat specifically the --stdlib:zero target. C# is quite a bit more than just enhanced C if you remove GC-reliant features as the generics and interface constraints enable a huge subset of features, alongside SIMD API, stack-allocated buffers and all sorts of memory wrappable in Span<T>s, which almost every method in the standard library that works on some sort of buffer accepts nowadays instead of plain arrays. You can also manually allocate objects - there are multiple ways to go about it and even with the presence of GC, there is a "hidden" but supported API to register a NonGC heap that GC understands when scanning object references. Though effective targeting is limited to much fewer count of platforms. Mono can target as low as ARMv6 but CoreCLR/NativeAOT mainly work with x86, x86_64, ARM and ARM64. For microcontrollers you are better off using Rust in my opinion. But for anything bigger .NET can be a surprisingly capable choice.
- dgellow 2y agoWould you be ok sharing more details how you combine both? I’ve been experimenting with this for a personal project, but integrating zig in a .NET solution has been fairly messy. Would love to read others experiences doing so successfully
- superfist 2y agoI should be more precise, I don't use them in same project. I am C# professional but using Zig for simple embedded programing projects and some tools that don't have requirment for complex runtime. If I would have to glue them together then I would probably compile Zig to webassembly component and use it in C# hosted env.
- neonsunset 2y agoUsing wasm for this sounds like a difficult and wasteful approach. Is there a reason you are avoiding a simple compilation of Zig part of codebase into a dynamically or statically linked library and calling into it with P/Invoke? You only need a `Target` and maybe `None Include=...` items in .csproj to instrument MSBuild to hook the building process of Zig into dotnet build and co.
- superfist 2y agoYes, P/Invoke should work, especially when you are targeting a single platform. However, for multiple platforms, there might be some unexpected obstacles I am not aware of.
- neonsunset 2y agoThe answer to this is to map the RID to the argument passed to Zig. Or just build on a target platform as an alternative, if possible. WASM is not a solution and would not work properly. It is the last resort effort in language with inferior interop capabilities. I'm just putting a disclaimer that using WASM is a very wrong kind of suggestion, would likely not work the way you expect it to (you would have to use WASM for .NET too which is in many places experimental and is a huge performance killer) and no one does it - there are appropriate ways to target multiple platforms in a solution that splits logic between .NET and C/C++/Rust/Zig/Swift/etc., especially that Zig offers nice cross-compilation toolchain. Mind you, the use case for this is accessing language-specific libraries and for performance the solution really is writing faster C# instead.