Hacker News new | past | comments | ask | show | jobs | submit login

.Net was built for interop (mostly with COM+, but that's close enough to C ABI once you get a function pointer). It's pretty good at making it easy. GCHandle and pinning in general aren't incredibly rare, heck, merely passing a byte array or string to a native function involves pinning. There's also all the heavy lifting it does for you: it doesn't look like you need to pin byte arrays because the JIT does that for you. .Net's safety invariants aren't that hard to uphold either (any more than C).

I have lost all love for the platform, but I still have to hand it to Microsoft: no FFI has come anywhere close to .Net in the 25-odd years of its existence.

> How would C track references for heap-allocated data originating from (A)RC-based language?

Intentionally designed FF interfaces do not at all. C either delegates allocation to the host language, or the host language needs to let C know when it's done with things. I think Lua is an example of the former (it has been a while), the Vulkano crate is a living example of the latter.




Pinning is always done for heap-allocated GC memory, yes. Otherwise fixed statement does nothing for pointers/byrefs that originate from stack and it should be also a no-op for e.g. NativeMemory.Alloc-returned pointers.

On the other hand, GCHandles[0] are rare and only ever needed when you have complex object lifetime where, for example, the object reference needs to be passed back from unmanaged and object needs to survive in the meantime. The unmanaged code cannot interact with an object itself because it is not representable and would have arbitrary layout.

Today, there is support for multiple calling conventions and ways to interact with FFI. [UnmanagedCallersOnly] exports with NativeAOT-compiled libraries are C exports in the same way they are for the dynamic (or static) libraries compiled with GCC. Various flavours of function pointers have existed for a long time, yes. The most recent one allows to cast pointers directly to the desired unmanaged function signature within unsafe code, or create one given mentioned UnmanagedCallersOnly annotation on a C# method.

[0] https://learn.microsoft.com/en-us/dotnet/api/system.runtime.... note specific use case, it's not the bread and butter regular marshaling and pinning are




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: