How is Dart FFI implemented indeed? Are they as cheap as a normal function call, or do they do heavy lifting under the hood?
Dart FFI uses C's dlopen() for platforms other than Windows (non-POSIX). It's a very lightweight interface to shared objects. Compiled shared objects contain a table with symbol names and their memory offset. The shared object is opened with dlopen() then specific contained items are found in memory using dlsym() with their symbol name. This provides a memory address for, say, a function with the name 'testDartFFI()'. The dart runtime can then call this function with the memory address, using the Dart prototype to correctly pass and return values based on C standards. Overhead-wise it's not much different than calling other dynamically linked system libraries.
Comments
-
ch271828n over 1 year
I am quite interested in how Dart FFI is implemented. Are they as cheap as a normal function call, or do they do heavy lifting under the hood?
I have searched through the Internet but cannot find much information. I only find this article talking a bit about the insights of argument passing and ABIs. In addition, I guess it should have some protections because Dart has things like GC while C does not.
Thanks for any hints!
-
ch271828n over 2 yearsThanks for the answer!
Overhead-wise it's not much different than calling other dynamically linked system libraries.
- When talking about overhead, I wonder the overhead of "Dart to C" compared with things like "Dart to Dart" or "C to C". Could you please elaborate? -
Pat9RB over 2 yearsExecutables that include calls to shared objects (.so/.dll) have an external symbol table in them. When the executable is loaded, before main() or similar is called, the linker makes sure the libraries are available and fills in the table with the memory addresses of the symbols. Once the executable starts running, every external it will need has an address. With dlopen(), the library is loaded after main() then the executable has to look up any symbol (function, global, etc) it wants to use. Once the symbols are resolved, arguments and returns would be the same overhead as any libc call.
-
Pat9RB over 2 yearsI've just started working with FFI though. (Trying to do C bindings for a C++ lib so I can then do Dart bindings for the C++ lib)
-
ch271828n over 2 yearsThanks!
Trying to do C bindings for a C++ lib so I can then do Dart bindings for the C++ lib
by the way you may be interested in: github.com/fzyzcjy/flutter_rust_bridge