For binders (i.e. wrappers) you use or should be using PythonCall.jl (main option now). A lot of Python package also have C or C++ code, but usually still only Python API, so you only need to call it, and indirectly the other implementation languages, so you likely never need to think of calling C or C++, bypassing Python API. I believe PythonCall.jl is the most systematic “automated” there is if you mean that, and you do not have to make a binding package, but you can, mainly to help others, and then you would still use it.
What you do depends on the language, i.e. what language you want to bind to most directly, e.g. for C++ CxxWrap.jl is recommended (there are more packages like GitHub - timholy/Cpp.jl: Utilities for calling C++ from Julia I believe all or most outdated/redundant), if there’s no C API already, but very commonly such exists for C++ code, at least if meant to be wrapped, but if a C API is available, the C++ code just functions like calling any other C code, and you just use ccall
keyword, to call a dynamic link library.
Note FFTW.jl depends on FFTW_jll (for the compiled C code, all you need to call for it, despite implemented by OCaml too; and see also GR_jll, also implemented in C), for binary, code, it’s common to have a jll, for the compiled C code or whatever other compiled language.
For Scala you use JavaCall.jl, and well for Java to and some more lagnuages, likely e.g. for Kotlin, should be possible.
To call from C you embed Julia in it, and call from C (indirectly this is done for you with the packages like JuliaCall, for Python or e.g. R; and sometimes you embed yourself too this way for e.g. C++, Fortran or Rust):
For Rust though you likely use:
https://crates.io/crates/jlrs/
You can use node-julia
, and something for Ruby, Lua, C# etc. to call to or from.
You could call C code from the start with ccall
(or use it to call Fortran and more even Rust), but not there’s also:
And to help call C [API], e.g. also for C++ code, you can use Clang.jl: