Also, because symbol resolution is done at compile-time, this is a non starter for something like JRuby, wherein one would want to write plain Ruby code to call a C function — rather than writing Ruby, Java and JNI flavored C code. Ruby is an interpreted language, so calling into or out of C requires dynamic symbol resolution, and for the C->Ruby callback case, a closure must be created on the fly (that is, a C ABI function must be JIT compiled for that method or proc). This isn’t particular to Ruby — any interpreted language will run into this issue on the JVM (picture Python and its ctypes and/or cffi libraries).
You can see some of the hoops that JRuby had to jump through to support this use case, in order to provide a JRuby implementation of the ‘ffi’ gem interface:
https://javadoc.io/doc/org.jruby/jruby-core/9.2.13.0/org/jru...
https://www.igvita.com/2009/01/15/bridging-mri-jruby-rubiniu...
It’s been a minute, so my recollection may be wrong, but IIRC JRuby uses Java and JNI to call into a C shim that then calls into libffi to handle things like creating C ABI conforming closures and such on the fly (the ffi gem on CRuby also uses libffi for the same purposes).
Correction: I believe JRuby uses JNA, which in turn is Java+JNI to call C that then calls into libffi, which is then leveraged to call whatever other functions (or create C callbacks back into the JVM). So I’m pretty sure FFM would be an officially supported replacement (maybe superset?) of JNA. (I’m on vacation and typed all of this out on my phone, so forgive me if I got some details a bit off)
I’m pretty sure that just about all of that complexity can be ripped out once FFM is generally available.