Interoperability

Types: Cint, Cdouble, Cstring, Ptr{T}, Ref{T}, Cvoid; struct layouts match C for isbits structs.

31.1 C and Fortran (built-in, zero overhead)

Types: Cint, Cdouble, Cstring, Ptr{T}, Ref{T}, Cvoid; struct layouts match C for isbits structs. Clang.jl generates wrappers from headers; BinaryBuilder.jl/Yggdrasil provide prebuilt binaries as _jll packages (using LibCURL_jll).

# Call a C library function
t = ccall(:clock, Int32, ())
len = ccall(:strlen, Csize_t, (Cstring,), "hello")       # 5
@ccall strlen("hello"::Cstring)::Csize_t                   # macro form (1.5+)

# Call your own shared library
# gcc -shared -fPIC -o libmylib.so mylib.c
@ccall "./libmylib.so".add(2::Cint, 3::Cint)::Cint

# Fortran (pass by reference, name mangling with trailing underscore)
# ccall((:dot_, "libfort.so"), Float64, (Ref{Int32}, Ptr{Float64}, Ptr{Float64}), n, x, y)

# Callbacks: pass Julia functions to C
cmp(a, b) = Cint(sign(unsafe_load(a) - unsafe_load(b)))
cfun = @cfunction(cmp, Cint, (Ptr{Cdouble}, Ptr{Cdouble}))
v = [3.0, 1.0, 2.0]
ccall(:qsort, Cvoid, (Ptr{Cdouble}, Csize_t, Csize_t, Ptr{Cvoid}), v, length(v), sizeof(Cdouble), cfun)

31.2 Python: PythonCall.jl (and PyCall.jl)

Calling Julia from Python: juliacall (from juliacall import Main as jl; jl.seval("1+1")). CondaPkg.jl manages Python dependencies.

using PythonCall
np = pyimport("numpy")
x = np.linspace(0, 1, 5)
pyconvert(Vector{Float64}, x)
plt = pyimport("matplotlib.pyplot")
@py import sklearn.datasets as ds

31.3 R, C++, MATLAB, Java

RCall.jl: R"summary(lm(mpg ~ wt, data = mtcars))", @rput, @rget.

CxxWrap.jl: wrap C++ libraries.

MATLAB.jl, JavaCall.jl, ObjectiveC.jl.

Embedding Julia in C/C++ via julia.h (jl_init, jl_eval_string).