### [Bits Types](#man-bits-types)
```c
int main(int argc, char **argv);
```
can be called via the following Julia code:
```julia
argv = [ "a.out", "arg1", "arg2" ]
@ccall main(length(argv)::Int32, argv::Ptr{Ptr{UInt8}})::Int32
```
For Fortran functions taking variable length strings of type `character(len=*)` the string lengths are provided as *hidden arguments*. Type and position of these arguments in the list are compiler specific, where compiler vendors usually default to using `Csize_t` as type and append the hidden arguments at the end of the argument list. While this behaviour is fixed for some compilers (GNU), others *optionally* permit placing hidden arguments directly after the character argument (Intel, PGI). For example, Fortran subroutines of the form
```fortran
subroutine test(str1, str2)
character(len=*) :: str1,str2
```
can be called via the following Julia code, where the lengths are appended
```julia
str1 = "foo"
str2 = "bar"
ccall(:test, Cvoid, (Ptr{UInt8}, Ptr{UInt8}, Csize_t, Csize_t),
                    str1, str2, sizeof(str1), sizeof(str2))
```
Fortran compilers *may* also add other hidden arguments for pointers, assumed-shape (`:`) and assumed-size (`*`) arrays. Such behaviour can be avoided by using `ISO_C_BINDING` and including `bind(c)` in the definition of the subroutine, which is strongly recommended for interoperable code. In this case, there will be no hidden arguments, at the cost of some language features (e.g. only `character(len=1)` will be permitted to pass strings).


### [Bits Types](#man-bits-types)
A C function declared to return `Cvoid` will return the value `nothing` in Julia.


### [Struct Type Correspondences](#Struct-Type-Correspondences)
Composite types such as `struct` in C or `TYPE` in Fortran90 (or `STRUCTURE` / `RECORD` in some variants of F77), can be mirrored in Julia by creating a `struct` definition with the same field layout.
When used recursively, `isbits` types are stored inline. All other types are stored as a pointer to the data. When mirroring a struct used by-value inside another struct in C, it is imperative that you do not attempt to manually copy the fields over, as this will not preserve the correct field alignment. Instead, declare an `isbits` struct type and use that instead. Unnamed structs are not possible in the translation to Julia.
Packed structs and union declarations are not supported by Julia.
You can get an approximation of a `union` if you know, a priori, the field that will have the greatest size (potentially including padding). When translating your fields to Julia, declare the Julia field to be only of that type.
Arrays of parameters can be expressed with `NTuple`. For example, the struct in C notation is written as
```c
struct B {
    int A[3];
};

b_a_2 = B.A[2];
```
can be written in Julia as
```julia
struct B
    A::NTuple{3, Cint}
end

b_a_2 = B.A[3]  # note the difference in indexing (1-based in Julia, 0-based in C)
```
Arrays of unknown size (C99-compliant variable length structs specified by `[]` or `[0]`) are not directly supported. Often the best way to deal with these is to deal with the byte offsets directly. For example, if a C library declared a proper string type and returned a pointer to it:


### [Struct Type Correspondences](#Struct-Type-Correspondences)
```c
struct String {
    int strlen;
    char data[];
};
```
In Julia, we can access the parts independently to make a copy of that string:
```julia
str = from_c::Ptr{Cvoid}
len = unsafe_load(Ptr{Cint}(str))
unsafe_string(str + Core.sizeof(Cint), len)
```


### [Type Parameters](#Type-Parameters)
The type arguments to `@ccall` and `@cfunction` are evaluated statically, when the method containing the usage is defined. They therefore must take the form of a literal tuple, not a variable, and cannot reference local variables.
This may sound like a strange restriction, but remember that since C is not a dynamic language like Julia, its functions can only accept argument types with a statically-known, fixed signature.
However, while the type layout must be known statically to compute the intended C ABI, the static parameters of the function are considered to be part of this static environment. The static parameters of the function may be used as type parameters in the call signature, as long as they don't affect the layout of the type. For example, `f(x::T) where {T} = @ccall valid(x::Ptr{T})::Ptr{T}` is valid, since `Ptr` is always a word-size primitive type. But, `g(x::T) where {T} = @ccall notvalid(x::T)::T` is not valid, since the type layout of `T` is not known statically.


### [SIMD Values](#SIMD-Values)
If a C/C++ routine has an argument or return value that is a native SIMD type, the corresponding Julia type is a homogeneous tuple of `VecElement` that naturally maps to the SIMD type. Specifically:
> -   The tuple must be the same size and elements as the SIMD type. For example, a tuple representing an `__m128` on x86 must have a size of 16 bytes and Float32 elements.
> -   The element type of the tuple must be an instance of `VecElement{T}` where `T` is a primitive type with a power-of-two number of bytes (e.g. 1, 2, 4, 8, 16, etc) such as Int8 or Float64.
For instance, consider this C routine that uses AVX intrinsics:
```c
#include <immintrin.h>

__m256 dist( __m256 a, __m256 b ) {
    return _mm256_sqrt_ps(_mm256_add_ps(_mm256_mul_ps(a, a),
                                        _mm256_mul_ps(b, b)));
}
```
The following Julia code calls `dist` using `ccall`:
```julia
const m256 = NTuple{8, VecElement{Float32}}

a = m256(ntuple(i -> VecElement(sin(Float32(i))), 8))
b = m256(ntuple(i -> VecElement(cos(Float32(i))), 8))

function call_dist(a::m256, b::m256)
    @ccall "libdist".dist(a::m256, b::m256)::m256
end

println(call_dist(a,b))
```
The host machine must have the requisite SIMD registers. For example, the code above will not work on hosts without AVX support.


### [Memory Ownership](#Memory-Ownership)
**`malloc`/`free`**
Memory allocation and deallocation of such objects must be handled by calls to the appropriate cleanup routines in the libraries being used, just like in any C program. Do not try to free an object received from a C library with [`Libc.free`](../../base/libc/#Base.Libc.free) in Julia, as this may result in the `free` function being called via the wrong library and cause the process to abort. The reverse (passing an object allocated in Julia to be freed by an external library) is equally invalid.


### [When to use T, Ptr{T} and Ref{T}](#When-to-use-T,-Ptr%7BT%7D-and-Ref%7BT%7D)
In Julia code wrapping calls to external C routines, ordinary (non-pointer) data should be declared to be of type `T` inside the `@ccall`, as they are passed by value. For C code accepting pointers, [`Ref{T}`](../../base/c/#Core.Ref) should generally be used for the types of input arguments, allowing the use of pointers to memory managed by either Julia or C through the implicit call to [`Base.cconvert`](../../base/c/#Base.cconvert). In contrast, pointers returned by the C function called should be declared to be of the output type [`Ptr{T}`](../../base/c/#Core.Ptr), reflecting that the memory pointed to is managed by C only. Pointers contained in C structs should be represented as fields of type `Ptr{T}` within the corresponding Julia struct types designed to mimic the internal structure of corresponding C structs.
In Julia code wrapping calls to external Fortran routines, all input arguments should be declared as of type `Ref{T}`, as Fortran passes all variables by pointers to memory locations. The return type should either be `Cvoid` for Fortran subroutines, or a `T` for Fortran functions returning the type `T`.


## [Mapping C Functions to Julia](#Mapping-C-Functions-to-Julia)


### [@ccall / @cfunction argument translation guide](#@ccall-/-@cfunction-argument-translation-guide)
For translating a C argument list to Julia:
-   `T`, where `T` is one of the primitive types: `char`, `int`, `long`, `short`, `float`, `double`, `complex`, `enum` or any of their `typedef` equivalents
    -   `T`, where `T` is an equivalent Julia Bits Type (per the table above)
    -   if `T` is an `enum`, the argument type should be equivalent to `Cint` or `Cuint`
    -   argument value will be copied (passed by value)
-   `struct T` (including typedef to a struct)
    -   `T`, where `T` is a Julia leaf type
    -   argument value will be copied (passed by value)
-   `vector T` (or `__attribute__ vector_size`, or a typedef such as `__m128`)
    -   `NTuple{N, VecElement{T}}`, where `T` is a primitive Julia type of the correct size and N is the number of elements in the vector (equal to `vector_size / sizeof T`).
-   `void*`
    -   depends on how this parameter is used, first translate this to the intended pointer type, then determine the Julia equivalent using the remaining rules in this list
    -   this argument may be declared as `Ptr{Cvoid}` if it really is just an unknown pointer
-   `jl_value_t*`
    -   `Any`
    -   argument value must be a valid Julia object
-   `jl_value_t* const*`
    -   `Ref{Any}`
    -   argument list must be a valid Julia object (or `C_NULL`)
    -   cannot be used for an output parameter, unless the user is able to separately arrange for the object to be GC-preserved
-   `T*`


### [@ccall / @cfunction argument translation guide](#@ccall-/-@cfunction-argument-translation-guide)
    -   `Ref{T}`, where `T` is the Julia type corresponding to `T`
    -   argument value will be copied if it is an `inlinealloc` type (which includes `isbits` otherwise, the value must be a valid Julia object
-   `T (*)(...)` (e.g. a pointer to a function)
    -   `Ptr{Cvoid}` (you may need to use [`@cfunction`](../../base/c/#Base.@cfunction) explicitly to create this pointer)
-   `...` (e.g. a vararg)
    -   \[for `ccall`\]: `T...`, where `T` is the single Julia type of all remaining arguments
    -   \[for `@ccall`\]: `; va_arg1::T, va_arg2::S, etc`, where `T` and `S` are the Julia type (i.e. separate the regular arguments from varargs with a `;`)
    -   currently unsupported by `@cfunction`
-   `va_arg`
    -   not supported by `ccall` or `@cfunction`


### [@ccall / @cfunction return type translation guide](#@ccall-/-@cfunction-return-type-translation-guide)
For translating a C return type to Julia:
-   `void`
    -   `Cvoid` (this will return the singleton instance `nothing::Cvoid`)
-   `T`, where `T` is one of the primitive types: `char`, `int`, `long`, `short`, `float`, `double`, `complex`, `enum` or any of their `typedef` equivalents
    -   same as C argument list
    -   argument value will be copied (returned by-value)
-   `struct T` (including typedef to a struct)
    -   same as C argument list
    -   argument value will be copied (returned by-value)
-   `vector T`
    -   same as C argument list
-   `void*`
    -   depends on how this parameter is used, first translate this to the intended pointer type, then determine the Julia equivalent using the remaining rules in this list
    -   this argument may be declared as `Ptr{Cvoid}` if it really is just an unknown pointer
-   `jl_value_t*`
    -   `Any`
    -   argument value must be a valid Julia object
-   `jl_value_t**`
    -   `Ptr{Any}` (`Ref{Any}` is invalid as a return type)
-   `T*`
    -   If the memory is already owned by Julia, or is an `isbits` type, and is known to be non-null:
        -   `Ref{T}`, where `T` is the Julia type corresponding to `T`
        -   a return type of `Ref{Any}` is invalid, it should either be `Any` (corresponding to `jl_value_t*`) or `Ptr{Any}` (corresponding to `jl_value_t**`)
        -   C **MUST NOT** modify the memory returned via `Ref{T}` if `T` is an `isbits` type
    -   If the memory is owned by C:


### [@ccall / @cfunction return type translation guide](#@ccall-/-@cfunction-return-type-translation-guide)
        -   `Ptr{T}`, where `T` is the Julia type corresponding to `T`
-   `T (*)(...)` (e.g. a pointer to a function)
    -   `Ptr{Cvoid}` to call this directly from Julia you will need to pass this as the first argument to `@ccall`. See [Indirect Calls](#Indirect-Calls).


### [Passing Pointers for Modifying Inputs](#Passing-Pointers-for-Modifying-Inputs)
Because C doesn't support multiple return values, often C functions will take pointers to data that the function will modify. To accomplish this within a `@ccall`, you need to first encapsulate the value inside a [`Ref{T}`](../../base/c/#Core.Ref) of the appropriate type. When you pass this `Ref` object as an argument, Julia will automatically pass a C pointer to the encapsulated data:
```julia
width = Ref{Cint}(0)
range = Ref{Cfloat}(0)
@ccall foo(width::Ref{Cint}, range::Ref{Cfloat})::Cvoid
```
Upon return, the contents of `width` and `range` can be retrieved (if they were changed by `foo`) by `width[]` and `range[]`; that is, they act like zero-dimensional arrays.


## [C Wrapper Examples](#C-Wrapper-Examples)
Let's start with a simple example of a C wrapper that returns a `Ptr` type:
```julia
mutable struct gsl_permutation
end

# The corresponding C signature is
#     gsl_permutation * gsl_permutation_alloc (size_t n);
function permutation_alloc(n::Integer)
    output_ptr = @ccall "libgsl".gsl_permutation_alloc(n::Csize_t)::Ptr{gsl_permutation}
    if output_ptr == C_NULL # Could not allocate memory
        throw(OutOfMemoryError())
    end
    return output_ptr
end
```
The [GNU Scientific Library](https://www.gnu.org/software/gsl/) (here assumed to be accessible through `:libgsl`) defines an opaque pointer, `gsl_permutation *`, as the return type of the C function `gsl_permutation_alloc`. As user code never has to look inside the `gsl_permutation` struct, the corresponding Julia wrapper simply needs a new type declaration, `gsl_permutation`, that has no internal fields and whose sole purpose is to be placed in the type parameter of a `Ptr` type. The return type of the [`ccall`](../../base/c/#ccall) is declared as `Ptr{gsl_permutation}`, since the memory allocated and pointed to by `output_ptr` is controlled by C.


## [C Wrapper Examples](#C-Wrapper-Examples)
The input `n` is passed by value, and so the function's input signature is simply declared as `::Csize_t` without any `Ref` or `Ptr` necessary. (If the wrapper was calling a Fortran function instead, the corresponding function input signature would instead be `::Ref{Csize_t}`, since Fortran variables are passed by pointers.) Furthermore, `n` can be any type that is convertible to a `Csize_t` integer; the [`ccall`](../../base/c/#ccall) implicitly calls [`Base.cconvert(Csize_t, n)`](../../base/c/#Base.cconvert).
Here is a second example wrapping the corresponding destructor:
```julia
# The corresponding C signature is
#     void gsl_permutation_free (gsl_permutation * p);
function permutation_free(p::Ptr{gsl_permutation})
    @ccall "libgsl".gsl_permutation_free(p::Ptr{gsl_permutation})::Cvoid
end
```
Here is a third example passing Julia arrays:
```julia
# The corresponding C signature is
#    int gsl_sf_bessel_Jn_array (int nmin, int nmax, double x,
#                                double result_array[])
function sf_bessel_Jn_array(nmin::Integer, nmax::Integer, x::Real)
    if nmax < nmin
        throw(DomainError())
    end
    result_array = Vector{Cdouble}(undef, nmax - nmin + 1)
    errorcode = @ccall "libgsl".gsl_sf_bessel_Jn_array(
                    nmin::Cint, nmax::Cint, x::Cdouble, result_array::Ref{Cdouble})::Cint
    if errorcode != 0
        error("GSL error code $errorcode")
    end
    return result_array
end
```


## [C Wrapper Examples](#C-Wrapper-Examples)
The C function wrapped returns an integer error code; the results of the actual evaluation of the Bessel J function populate the Julia array `result_array`. This variable is declared as a `Ref{Cdouble}`, since its memory is allocated and managed by Julia. The implicit call to [`Base.cconvert(Ref{Cdouble}, result_array)`](../../base/c/#Base.cconvert) unpacks the Julia pointer to a Julia array data structure into a form understandable by C.


## [Fortran Wrapper Example](#Fortran-Wrapper-Example)
The following example utilizes `ccall` to call a function in a common Fortran library (libBLAS) to compute a dot product. Notice that the argument mapping is a bit different here than above, as we need to map from Julia to Fortran. On every argument type, we specify `Ref` or `Ptr`. This mangling convention may be specific to your Fortran compiler and operating system and is likely undocumented. However, wrapping each in a `Ref` (or `Ptr`, where equivalent) is a frequent requirement of Fortran compiler implementations:
```julia
function compute_dot(DX::Vector{Float64}, DY::Vector{Float64})
    @assert length(DX) == length(DY)
    n = length(DX)
    incx = incy = 1
    product = @ccall "libLAPACK".ddot(
        n::Ref{Int32}, DX::Ptr{Float64}, incx::Ref{Int32}, DY::Ptr{Float64}, incy::Ref{Int32})::Float64
    return product
end
```


## [Garbage Collection Safety](#Garbage-Collection-Safety)
When passing data to a `@ccall`, it is best to avoid using the [`pointer`](../../base/c/#Base.pointer) function. Instead define a [`Base.cconvert`](../../base/c/#Base.cconvert) method and pass the variables directly to the `@ccall`. `@ccall` automatically arranges that all of its arguments will be preserved from garbage collection until the call returns. If a C API will store a reference to memory allocated by Julia, after the `@ccall` returns, you must ensure that the object remains visible to the garbage collector. The suggested way to do this is to make a global variable of type `Array{Ref,1}` to hold these values until the C library notifies you that it is finished with them.
Whenever you have created a pointer to Julia data, you must ensure the original data exists until you have finished using the pointer. Many methods in Julia such as [`unsafe_load`](../../base/c/#Base.unsafe_load) and [`String`](../../base/strings/#Core.String-Tuple%7BAbstractString%7D) make copies of data instead of taking ownership of the buffer, so that it is safe to free (or alter) the original data without affecting Julia. A notable exception is [`unsafe_wrap`](../../base/c/#Base.unsafe_wrap-Union%7BTuple%7BN%7D,%20Tuple%7BT%7D,%20Tuple%7BUnion%7BType%7BArray%7D,%20Type%7BArray%7BT%7D%7D,%20Type%7BArray%7BT,%20N%7D%7D%7D,%20Ptr%7BT%7D,%20NTuple%7BN,%20Int64%7D%7D%7D%20where%20%7BT,%20N%7D) which, for performance reasons, shares (or can be told to take ownership of) the underlying buffer.


## [Garbage Collection Safety](#Garbage-Collection-Safety)
The garbage collector does not guarantee any order of finalization. That is, if `a` contained a reference to `b` and both `a` and `b` are due for garbage collection, there is no guarantee that `b` would be finalized after `a`. If proper finalization of `a` depends on `b` being valid, it must be handled in other ways.


## [Non-constant Function Specifications](#Non-constant-Function-Specifications)
In some cases, the exact name or path of the needed library is not known in advance and must be computed at run time. To handle such cases, the library component specification can be a function call, e.g. `find_blas().dgemm`. The call expression will be executed when the `ccall` itself is executed. However, it is assumed that the library location does not change once it is determined, so the result of the call can be cached and reused. Therefore, the number of times the expression executes is unspecified, and returning different values for multiple calls results in unspecified behavior.
If even more flexibility is needed, it is possible to use computed values as function names by staging through [`eval`](../../base/base/#eval) as follows:
```julia
@eval @ccall "lib".$(string("a", "b"))()::Cint
```
This expression constructs a name using `string`, then substitutes this name into a new `@ccall` expression, which is then evaluated. Keep in mind that `eval` only operates at the top level, so within this expression local variables will not be available (unless their values are substituted with `$`). For this reason, `eval` is typically only used to form top-level definitions, for example when wrapping libraries that contain many similar functions. A similar example can be constructed for [`@cfunction`](../../base/c/#Base.@cfunction).


## [Non-constant Function Specifications](#Non-constant-Function-Specifications)
However, doing this will also be very slow and leak memory, so you should usually avoid this and instead keep reading. The next section discusses how to use indirect calls to efficiently achieve a similar effect.


## [Indirect Calls](#Indirect-Calls)
The first argument to `@ccall` can also be an expression evaluated at run time. In this case, the expression must evaluate to a `Ptr`, which will be used as the address of the native function to call. This behavior occurs when the first `@ccall` argument contains references to non-constants, such as local variables, function arguments, or non-constant globals.
For example, you might look up the function via `dlsym`, then cache it in a shared reference for that session. For example:
```julia
macro dlsym(lib, func)
    z = Ref{Ptr{Cvoid}}(C_NULL)
    quote
        let zlocal = $z[]
            if zlocal == C_NULL
                zlocal = dlsym($(esc(lib))::Ptr{Cvoid}, $(esc(func)))::Ptr{Cvoid}
                $z[] = zlocal
            end
            zlocal
        end
    end
end

mylibvar = Libdl.dlopen("mylib")
@ccall $(@dlsym(mylibvar, "myfunc"))()::Cvoid
```


## [Closure cfunctions](#Closure-cfunctions)
The first argument to [`@cfunction`](../../base/c/#Base.@cfunction) can be marked with a `$`, in which case the return value will instead be a `struct CFunction` which closes over the argument. You must ensure that this return object is kept alive until all uses of it are done. The contents and code at the cfunction pointer will be erased via a [`finalizer`](../../base/base/#Base.finalizer) when this reference is dropped and atexit. This is not usually needed, since this functionality is not present in C, but can be useful for dealing with ill-designed APIs which don't provide a separate closure environment parameter.
```julia
function qsort(a::Vector{T}, cmp) where T
    isbits(T) || throw(ArgumentError("this method can only qsort isbits arrays"))
    callback = @cfunction $cmp Cint (Ref{T}, Ref{T})
    # Here, `callback` isa Base.CFunction, which will be converted to Ptr{Cvoid}
    # (and protected against finalization) by the ccall
    @ccall qsort(a::Ptr{T}, length(a)::Csize_t, Base.elsize(a)::Csize_t, callback::Ptr{Cvoid})
    # We could instead use:
    #    GC.@preserve callback begin
    #        use(Base.unsafe_convert(Ptr{Cvoid}, callback))
    #    end
    # if we needed to use it outside of a `ccall`
    return a
end
```
Closure [`@cfunction`](../../base/c/#Base.@cfunction) relies on LLVM trampolines, which are not available on all platforms (for example ARM and PowerPC).


## [Closing a Library](#Closing-a-Library)
It is sometimes useful to close (unload) a library so that it can be reloaded. For instance, when developing C code for use with Julia, one may need to compile, call the C code from Julia, then close the library, make an edit, recompile, and load in the new changes. One can either restart Julia or use the `Libdl` functions to manage the library explicitly, such as:
```julia
lib = Libdl.dlopen("./my_lib.so") # Open the library explicitly.
sym = Libdl.dlsym(lib, :my_fcn)   # Get a symbol for the function to call.
@ccall $sym(...) # Use the pointer `sym` instead of the library.symbol tuple.
Libdl.dlclose(lib) # Close the library explicitly.
```
Note that when using `@ccall` with the input (e.g., `@ccall "./my_lib.so".my_fcn(...)::Cvoid`), the library is opened implicitly and it may not be explicitly closed.


## [Variadic function calls](#Variadic-function-calls)
To call variadic C functions a `semicolon` can be used in the argument list to separate required arguments from variadic arguments. An example with the `printf` function is given below:
```julia-repl
julia> @ccall printf("%s = %d\n"::Cstring ; "foo"::Cstring, foo::Cint)::Cint
foo = 3
8
```


## [ccall interface](#ccall-interface)
There is another alternative interface to `@ccall`. This interface is slightly less convenient but it does allow one to specify a [calling convention](#calling-convention).
The arguments to [`ccall`](../../base/c/#ccall) are:
1.  A `(:function, "library")` pair (most common),
    OR
    a `:function` name symbol or `"function"` name string (for symbols in the current process or libc),
    OR
    a function pointer (for example, from `dlsym`).
2.  The function's return type
3.  A tuple of input types, corresponding to the function signature. One common mistake is forgetting that a 1-tuple of argument types must be written with a trailing comma.
4.  The actual argument values to be passed to the function, if any; each is a separate parameter.
The `(:function, "library")` pair, return type, and input types must be literal constants (i.e., they can't be variables, but see [Non-constant Function Specifications](#Non-constant-Function-Specifications)).
The remaining parameters are evaluated at compile-time, when the containing method is defined.
A table of translations between the macro and function interfaces is given below.


## [ccall interface](#ccall-interface)
|                                                                     `@ccall` |                                                                     `ccall` |
|-----------------------------------------------------------------------------:|----------------------------------------------------------------------------:|
|                                                      `@ccall clock()::Int32` |                                                  `ccall(:clock, Int32, ())` |
|                                                    `@ccall f(a::Cint)::Cint` |                                               `ccall(:a, Cint, (Cint,), a)` |
|                               `@ccall "mylib".f(a::Cint, b::Cdouble)::Cvoid` |                      `ccall((:f, "mylib"), Cvoid, (Cint, Cdouble), (a, b))` |
|                                                    `@ccall $fptr.f()::Cvoid` |                                                 `ccall(fptr, f, Cvoid, ())` |
|      `@ccall printf("%s = %d\n"::Cstring ; "foo"::Cstring, foo::Cint)::Cint` |                                                             `<unavailable>` |
| `@ccall printf("%s = %s\n"::Cstring ; "2 + 2"::Cstring, "5"::Cstring)::Cint` |    `ccall(:printf, Cint, (Cstring, Cstring...), "%s = %s\n", "2 + 2", "5")` |
|                                                              `<unavailable>` | `ccall(:gethostname, stdcall, Int32, (Ptr{UInt8}, UInt32), hn, length(hn))` |


## [Calling Convention](#calling-convention)
The second argument to `ccall` (immediately preceding return type) can optionally be a calling convention specifier (the `@ccall` macro currently does not support giving a calling convention). Without any specifier, the platform-default C calling convention is used. Other supported conventions are: `stdcall`, `cdecl`, `fastcall`, and `thiscall` (no-op on 64-bit Windows). For example (from `base/libc.jl`) we see the same `gethostname``ccall` as above, but with the correct signature for Windows:
```julia
hn = Vector{UInt8}(undef, 256)
err = ccall(:gethostname, stdcall, Int32, (Ptr{UInt8}, UInt32), hn, length(hn))
```
For more information, please see the [LLVM Language Reference](https://llvm.org/docs/LangRef.html#calling-conventions).
There is one additional special calling convention [`llvmcall`](../../base/c/#Core.Intrinsics.llvmcall), which allows inserting calls to LLVM intrinsics directly. This can be especially useful when targeting unusual platforms such as GPGPUs. For example, for [CUDA](https://llvm.org/docs/NVPTXUsage.html), we need to be able to read the thread index:
```julia
ccall("llvm.nvvm.read.ptx.sreg.tid.x", llvmcall, Int32, ())
```
As with any `ccall`, it is essential to get the argument signature exactly correct. Also, note that there is no compatibility layer that ensures the intrinsic makes sense and works on the current target, unlike the equivalent Julia functions exposed by `Core.Intrinsics`.


## [Accessing Global Variables](#Accessing-Global-Variables)
Global variables exported by native libraries can be accessed by name using the [`cglobal`](../../base/c/#Core.Intrinsics.cglobal) function. The arguments to [`cglobal`](../../base/c/#Core.Intrinsics.cglobal) are a symbol specification identical to that used by [`ccall`](../../base/c/#ccall), and a type describing the value stored in the variable:
```julia-repl
julia> cglobal((:errno, :libc), Int32)
Ptr{Int32} @0x00007f418d0816b8
```
The result is a pointer giving the address of the value. The value can be manipulated through this pointer using [`unsafe_load`](../../base/c/#Base.unsafe_load) and [`unsafe_store!`](../../base/c/#Base.unsafe_store!).
This `errno` symbol may not be found in a library named "libc", as this is an implementation detail of your system compiler. Typically standard library symbols should be accessed just by name, allowing the compiler to fill in the correct one. Also, however, the `errno` symbol shown in this example is special in most compilers, and so the value seen here is probably not what you expect or want. Compiling the equivalent code in C on any multi-threaded-capable system would typically actually call a different function (via macro preprocessor overloading), and may give a different result than the legacy value printed here.


## [Accessing Data through a Pointer](#Accessing-Data-through-a-Pointer)
The following methods are described as "unsafe" because a bad pointer or type declaration can cause Julia to terminate abruptly.
Given a `Ptr{T}`, the contents of type `T` can generally be copied from the referenced memory into a Julia object using `unsafe_load(ptr, [index])`. The index argument is optional (default is 1), and follows the Julia-convention of 1-based indexing. This function is intentionally similar to the behavior of [`getindex`](../../base/collections/#Base.getindex) and [`setindex!`](../../base/collections/#Base.setindex!) (e.g. `[]` access syntax).
The return value will be a new object initialized to contain a copy of the contents of the referenced memory. The referenced memory can safely be freed or released.


## [Accessing Data through a Pointer](#Accessing-Data-through-a-Pointer)
If `T` is `Any`, then the memory is assumed to contain a reference to a Julia object (a `jl_value_t*`), the result will be a reference to this object, and the object will not be copied. You must be careful in this case to ensure that the object was always visible to the garbage collector (pointers do not count, but the new reference does) to ensure the memory is not prematurely freed. Note that if the object was not originally allocated by Julia, the new object will never be finalized by Julia's garbage collector. If the `Ptr` itself is actually a `jl_value_t*`, it can be converted back to a Julia object reference by [`unsafe_pointer_to_objref(ptr)`](../../base/c/#Base.unsafe_pointer_to_objref). (Julia values `v` can be converted to `jl_value_t*` pointers, as `Ptr{Cvoid}`, by calling [`pointer_from_objref(v)`](../../base/c/#Base.pointer_from_objref).)
The reverse operation (writing data to a `Ptr{T}`), can be performed using [`unsafe_store!(ptr, value, [index])`](../../base/c/#Base.unsafe_store!). Currently, this is only supported for primitive types or other pointer-free (`isbits`) immutable struct types.
Any operation that throws an error is probably currently unimplemented and should be posted as a bug so that it can be resolved.


## [Accessing Data through a Pointer](#Accessing-Data-through-a-Pointer)
If the pointer of interest is a plain-data array (primitive type or immutable struct), the function [`unsafe_wrap(Array, ptr,dims, own = false)`](../../base/c/#Base.unsafe_wrap-Union%7BTuple%7BN%7D,%20Tuple%7BT%7D,%20Tuple%7BUnion%7BType%7BArray%7D,%20Type%7BArray%7BT%7D%7D,%20Type%7BArray%7BT,%20N%7D%7D%7D,%20Ptr%7BT%7D,%20NTuple%7BN,%20Int64%7D%7D%7D%20where%20%7BT,%20N%7D) may be more useful. The final parameter should be true if Julia should "take ownership" of the underlying buffer and call `free(ptr)` when the returned `Array` object is finalized. If the `own` parameter is omitted or false, the caller must ensure the buffer remains in existence until all access is complete.
Arithmetic on the `Ptr` type in Julia (e.g. using `+`) does not behave the same as C's pointer arithmetic. Adding an integer to a `Ptr` in Julia always moves the pointer by some number of *bytes*, not elements. This way, the address values obtained from pointer arithmetic do not depend on the element types of pointers.


## [Thread-safety](#Thread-safety)
Some C libraries execute their callbacks from a different thread, and since Julia isn't thread-safe you'll need to take some extra precautions. In particular, you'll need to set up a two-layered system: the C callback should only *schedule* (via Julia's event loop) the execution of your "real" callback. To do this, create an [`AsyncCondition`](../../base/base/#Base.AsyncCondition) object and [`wait`](../../base/parallel/#Base.wait) on it:
```julia
cond = Base.AsyncCondition()
wait(cond)
```
The callback you pass to C should only execute a [`ccall`](../../base/c/#ccall) to `:uv_async_send`, passing `cond.handle` as the argument, taking care to avoid any allocations or other interactions with the Julia runtime.
Note that events may be coalesced, so multiple calls to `uv_async_send` may result in a single wakeup notification to the condition.


## [More About Callbacks](#More-About-Callbacks)
For more details on how to pass callbacks to C libraries, see this [blog post](https://julialang.org/blog/2013/05/callback).


## [C++](#C)
For tools to create C++ bindings, see the [CxxWrap](https://github.com/JuliaInterop/CxxWrap.jl) package.
-   [1](#citeref-1)Non-library function calls in both C and Julia can be inlined and thus may have even less overhead than calls to shared library functions. The point above is that the cost of actually doing foreign function call is about the same as doing a call in either native language.
-   [2](#citeref-2)The [Clang package](https://github.com/ihnorton/Clang.jl) can be used to auto-generate Julia code from a C header file.
------------------------------------------------------------------------


# Handling Operating System Variation · The Julia Language
Source: https://docs.julialang.org/en/v1/manual/handling-operating-system-variation/


# [Handling Operating System Variation](#Handling-Operating-System-Variation)
When writing cross-platform applications or libraries, it is often necessary to allow for differences between operating systems. The variable `Sys.KERNEL` can be used to handle such cases. There are several functions in the `Sys` module intended to make this easier, such as `isunix`, `islinux`, `isapple`, `isbsd`, `isfreebsd`, and `iswindows`. These may be used as follows:
```julia
if Sys.iswindows()
    windows_specific_thing(a)
end
```
Note that `islinux`, `isapple`, and `isfreebsd` are mutually exclusive subsets of `isunix`. Additionally, there is a macro `@static` which makes it possible to use these functions to conditionally hide invalid code, as demonstrated in the following examples.
Simple blocks:
```julia
ccall((@static Sys.iswindows() ? :_fopen : :fopen), ...)
```
Complex blocks:
```julia
@static if Sys.islinux()
    linux_specific_thing(a)
elseif Sys.isapple()
    apple_specific_thing(a)
else
    generic_thing(a)
end
```
When nesting conditionals, the `@static` must be repeated for each level (parentheses optional, but recommended for readability):
```julia
@static Sys.iswindows() ? :a : (@static Sys.isapple() ? :b : :c)
```
------------------------------------------------------------------------


# Environment Variables · The Julia Language
Source: https://docs.julialang.org/en/v1/manual/environment-variables/


# [Environment Variables](#Environment-Variables)
Julia can be configured with a number of environment variables, set either in the usual way for each operating system, or in a portable way from within Julia. Supposing that you want to set the environment variable [`JULIA_EDITOR`](#JULIA_EDITOR) to `vim`, you can type `ENV["JULIA_EDITOR"] = "vim"` (for instance, in the REPL) to make this change on a case by case basis, or add the same to the user configuration file `~/.julia/config/startup.jl` in the user's home directory to have a permanent effect. The current value of the same environment variable can be determined by evaluating `ENV["JULIA_EDITOR"]`.
The environment variables that Julia uses generally start with `JULIA`. If [`InteractiveUtils.versioninfo`](../../stdlib/InteractiveUtils/#InteractiveUtils.versioninfo) is called with the keyword `verbose=true`, then the output will list any defined environment variables relevant for Julia, including those which include `JULIA` in their names.
It is recommended to avoid changing environment variables during runtime, such as within a `~/.julia/config/startup.jl`.
One reason is that some julia language variables, such as [`JULIA_NUM_THREADS`](#JULIA_NUM_THREADS) and [`JULIA_PROJECT`](#JULIA_PROJECT), need to be set before Julia starts.
Similarly, `__init__()` functions of user modules in the sysimage (via PackageCompiler) are run before `startup.jl`, so setting environment variables in a `startup.jl` may be too late for user code.


# [Environment Variables](#Environment-Variables)
Further, changing environment variables during runtime can introduce data races into otherwise benign code.
In Bash, environment variables can either be set manually by running, e.g., `export JULIA_NUM_THREADS=4` before starting Julia, or by adding the same command to `~/.bashrc` or `~/.bash_profile` to set the variable each time Bash is started.


## [File locations](#File-locations)


### [`JULIA_BINDIR`](#JULIA_BINDIR)
The absolute path of the directory containing the Julia executable, which sets the global variable [`Sys.BINDIR`](../../base/constants/#Base.Sys.BINDIR). If `$JULIA_BINDIR` is not set, then Julia determines the value `Sys.BINDIR` at run-time.
The executable itself is one of
```julia
$JULIA_BINDIR/julia
$JULIA_BINDIR/julia-debug
```
by default.
The global variable `Base.DATAROOTDIR` determines a relative path from `Sys.BINDIR` to the data directory associated with Julia. Then the path
```julia
$JULIA_BINDIR/$DATAROOTDIR/julia/base
```
determines the directory in which Julia initially searches for source files (via `Base.find_source_file()`).
Likewise, the global variable `Base.SYSCONFDIR` determines a relative path to the configuration file directory. Then Julia searches for a `startup.jl` file at
```julia
$JULIA_BINDIR/$SYSCONFDIR/julia/startup.jl
$JULIA_BINDIR/../etc/julia/startup.jl
```
by default (via `Base.load_julia_startup()`).
For example, a Linux installation with a Julia executable located at `/bin/julia`, a `DATAROOTDIR` of `../share`, and a `SYSCONFDIR` of `../etc` will have [`JULIA_BINDIR`](#JULIA_BINDIR) set to `/bin`, a source-file search path of
```julia
/share/julia/base
```
and a global configuration search path of
```julia
/etc/julia/startup.jl
```


### [`JULIA_PROJECT`](#JULIA_PROJECT)
A directory path that indicates which project should be the initial active project. Setting this environment variable has the same effect as specifying the `--project` start-up option, but `--project` has higher precedence. If the variable is set to `@.` (note the trailing dot) then Julia tries to find a project directory that contains `Project.toml` or `JuliaProject.toml` file from the current directory and its parents. See also the chapter on [Code Loading](../code-loading/#code-loading).
[`JULIA_PROJECT`](#JULIA_PROJECT) must be defined before starting julia; defining it in `startup.jl` is too late in the startup process.


### [`JULIA_LOAD_PATH`](#JULIA_LOAD_PATH)
The [`JULIA_LOAD_PATH`](#JULIA_LOAD_PATH) environment variable is used to populate the global Julia [`LOAD_PATH`](../../base/constants/#Base.LOAD_PATH) variable, which determines which packages can be loaded via `import` and `using` (see [Code Loading](../code-loading/#code-loading)).
Unlike the shell `PATH` variable, empty entries in [`JULIA_LOAD_PATH`](#JULIA_LOAD_PATH) are expanded to the default value of `LOAD_PATH`, `["@", "@v#.#", "@stdlib"]` when populating `LOAD_PATH`. This allows easy appending, prepending, etc. of the load path value in shell scripts regardless of whether [`JULIA_LOAD_PATH`](#JULIA_LOAD_PATH) is already set or not. For example, to prepend the directory `/foo/bar` to `LOAD_PATH` just do
```sh
export JULIA_LOAD_PATH="/foo/bar:$JULIA_LOAD_PATH"
```


### [`JULIA_LOAD_PATH`](#JULIA_LOAD_PATH)
If the [`JULIA_LOAD_PATH`](#JULIA_LOAD_PATH) environment variable is already set, its old value will be prepended with `/foo/bar`. On the other hand, if [`JULIA_LOAD_PATH`](#JULIA_LOAD_PATH) is not set, then it will be set to `/foo/bar:` which will expand to a `LOAD_PATH` value of `["/foo/bar", "@", "@v#.#", "@stdlib"]`. If [`JULIA_LOAD_PATH`](#JULIA_LOAD_PATH) is set to the empty string, it expands to an empty `LOAD_PATH` array. In other words, the empty string is interpreted as a zero-element array, not a one-element array of the empty string. This behavior was chosen so that it would be possible to set an empty load path via the environment variable. If you want the default load path, either unset the environment variable or if it must have a value, set it to the string `:`.
On Windows, path elements are separated by the `;` character, as is the case with most path lists on Windows. Replace `:` with `;` in the above paragraph.


### [`JULIA_DEPOT_PATH`](#JULIA_DEPOT_PATH)
The [`JULIA_DEPOT_PATH`](#JULIA_DEPOT_PATH) environment variable is used to populate the global Julia [`DEPOT_PATH`](../../base/constants/#Base.DEPOT_PATH) variable, which controls where the package manager, as well as Julia's code loading mechanisms, look for package registries, installed packages, named environments, repo clones, cached compiled package images, configuration files, and the default location of the REPL's history file.
Unlike the shell `PATH` variable but similar to [`JULIA_LOAD_PATH`](#JULIA_LOAD_PATH), empty entries in [`JULIA_DEPOT_PATH`](#JULIA_DEPOT_PATH) have special behavior:
-   At the end, it is expanded to the default value of `DEPOT_PATH`, *excluding* the user depot.
-   At the start, it is expanded to the default value of `DEPOT_PATH`, *including* the user depot.
This allows easy overriding of the user depot, while still retaining access to resources that are bundled with Julia, like cache files, artifacts, etc. For example, to switch the user depot to `/foo/bar` use a trailing `:`
```sh
export JULIA_DEPOT_PATH="/foo/bar:"
```
All package operations, like cloning registrise or installing packages, will now write to `/foo/bar`, but since the empty entry is expanded to the default system depot, any bundled resources will still be available. If you really only want to use the depot at `/foo/bar`, and not load any bundled resources, simply set the environment variable to `/foo/bar` without the trailing colon.


### [`JULIA_DEPOT_PATH`](#JULIA_DEPOT_PATH)
To append a depot at the end of the full default list, including the default user depot, use a leading `:`
```sh
export JULIA_DEPOT_PATH=":/foo/bar"
```
There are two exceptions to the above rule. First, if [`JULIA_DEPOT_PATH`](#JULIA_DEPOT_PATH) is set to the empty string, it expands to an empty `DEPOT_PATH` array. In other words, the empty string is interpreted as a zero-element array, not a one-element array of the empty string. This behavior was chosen so that it would be possible to set an empty depot path via the environment variable.
Second, if no user depot is specified in [`JULIA_DEPOT_PATH`](#JULIA_DEPOT_PATH), then the empty entry is expanded to the default depot *including* the user depot. This makes it possible to use the default depot, as if the environment variable was unset, by setting it to the string `:`.
On Windows, path elements are separated by the `;` character, as is the case with most path lists on Windows. Replace `:` with `;` in the above paragraph.
[`JULIA_DEPOT_PATH`](#JULIA_DEPOT_PATH) must be defined before starting julia; defining it in `startup.jl` is too late in the startup process; at that point you can instead directly modify the `DEPOT_PATH` array, which is populated from the environment variable.


### [`JULIA_HISTORY`](#JULIA_HISTORY)
The absolute path `REPL.find_hist_file()` of the REPL's history file. If `$JULIA_HISTORY` is not set, then `REPL.find_hist_file()` defaults to
```julia
$(DEPOT_PATH[1])/logs/repl_history.jl
```


### [`JULIA_MAX_NUM_PRECOMPILE_FILES`](#JULIA_MAX_NUM_PRECOMPILE_FILES)
Sets the maximum number of different instances of a single package that are to be stored in the precompile cache (default = 10).


### [`JULIA_VERBOSE_LINKING`](#JULIA_VERBOSE_LINKING)
If set to true, linker commands will be displayed during precompilation.


## [Pkg.jl](#Pkg.jl)


### [`JULIA_CI`](#JULIA_CI)
If set to `true`, this indicates to the package server that any package operations are part of a continuous integration (CI) system for the purposes of gathering package usage statistics.


### [`JULIA_NUM_PRECOMPILE_TASKS`](#JULIA_NUM_PRECOMPILE_TASKS)
The number of parallel tasks to use when precompiling packages. See [`Pkg.precompile`](https://pkgdocs.julialang.org/v1/api/#Pkg.precompile).


### [`JULIA_PKG_DEVDIR`](#JULIA_PKG_DEVDIR)
The default directory used by [`Pkg.develop`](https://pkgdocs.julialang.org/v1/api/#Pkg.develop) for downloading packages.


### [`JULIA_PKG_IGNORE_HASHES`](#JULIA_PKG_IGNORE_HASHES)
If set to `1`, this will ignore incorrect hashes in artifacts. This should be used carefully, as it disables verification of downloads, but can resolve issues when moving files across different types of file systems. See [Pkg.jl issue #2317](https://github.com/JuliaLang/Pkg.jl/issues/2317) for more details.
This is only supported in Julia 1.6 and above.


### [`JULIA_PKG_OFFLINE`](#JULIA_PKG_OFFLINE)
If set to `true`, this will enable offline mode: see [`Pkg.offline`](https://pkgdocs.julialang.org/v1/api/#Pkg.offline).
Pkg's offline mode requires Julia 1.5 or later.


### [`JULIA_PKG_PRECOMPILE_AUTO`](#JULIA_PKG_PRECOMPILE_AUTO)
If set to `0`, this will disable automatic precompilation by package actions which change the manifest. See [`Pkg.precompile`](https://pkgdocs.julialang.org/v1/api/#Pkg.precompile).


### [`JULIA_PKG_SERVER`](#JULIA_PKG_SERVER)
Specifies the URL of the package registry to use. By default, `Pkg` uses `https://pkg.julialang.org` to fetch Julia packages. In addition, you can disable the use of the PkgServer protocol, and instead access the packages directly from their hosts (GitHub, GitLab, etc.) by setting: `export JULIA_PKG_SERVER=""`


### [`JULIA_PKG_SERVER_REGISTRY_PREFERENCE`](#JULIA_PKG_SERVER_REGISTRY_PREFERENCE)
Specifies the preferred registry flavor. Currently supported values are `conservative` (the default), which will only publish resources that have been processed by the storage server (and thereby have a higher probability of being available from the PkgServers), whereas `eager` will publish registries whose resources have not necessarily been processed by the storage servers. Users behind restrictive firewalls that do not allow downloading from arbitrary servers should not use the `eager` flavor.
This only affects Julia 1.7 and above.


### [`JULIA_PKG_UNPACK_REGISTRY`](#JULIA_PKG_UNPACK_REGISTRY)
If set to `true`, this will unpack the registry instead of storing it as a compressed tarball.
This only affects Julia 1.7 and above. Earlier versions will always unpack the registry.


### [`JULIA_PKG_USE_CLI_GIT`](#JULIA_PKG_USE_CLI_GIT)
If set to `true`, Pkg operations which use the git protocol will use an external `git` executable instead of the default libgit2 library.
Use of the `git` executable is only supported on Julia 1.7 and above.


### [`JULIA_PKGRESOLVE_ACCURACY`](#JULIA_PKGRESOLVE_ACCURACY)
The accuracy of the package resolver. This should be a positive integer, the default is `1`.


### [`JULIA_PKG_PRESERVE_TIERED_INSTALLED`](#JULIA_PKG_PRESERVE_TIERED_INSTALLED)
Change the default package installation strategy to `Pkg.PRESERVE_TIERED_INSTALLED` to let the package manager try to install versions of packages while keeping as many versions of packages already installed as possible.
This only affects Julia 1.9 and above.


## [Network transport](#Network-transport)


### [`JULIA_NO_VERIFY_HOSTS`](#JULIA_NO_VERIFY_HOSTS)


### [`JULIA_SSL_NO_VERIFY_HOSTS`](#JULIA_SSL_NO_VERIFY_HOSTS)


### [`JULIA_SSH_NO_VERIFY_HOSTS`](#JULIA_SSH_NO_VERIFY_HOSTS)


### [`JULIA_ALWAYS_VERIFY_HOSTS`](#JULIA_ALWAYS_VERIFY_HOSTS)
Specify hosts whose identity should or should not be verified for specific transport layers. See [`NetworkOptions.verify_host`](https://github.com/JuliaLang/NetworkOptions.jl#verify_host)


### [`JULIA_SSL_CA_ROOTS_PATH`](#JULIA_SSL_CA_ROOTS_PATH)
Specify the file or directory containing the certificate authority roots. See [`NetworkOptions.ca_roots`](https://github.com/JuliaLang/NetworkOptions.jl#ca_roots)


## [External applications](#External-applications)


### [`JULIA_SHELL`](#JULIA_SHELL)
The absolute path of the shell with which Julia should execute external commands (via `Base.repl_cmd()`). Defaults to the environment variable `$SHELL`, and falls back to `/bin/sh` if `$SHELL` is unset.
On Windows, this environment variable is ignored, and external commands are executed directly.


### [`JULIA_EDITOR`](#JULIA_EDITOR)
The editor returned by `InteractiveUtils.editor()` and used in, e.g., [`InteractiveUtils.edit`](../../stdlib/InteractiveUtils/#InteractiveUtils.edit-Tuple%7BAbstractString,%20Integer%7D), referring to the command of the preferred editor, for instance `vim`.
`$JULIA_EDITOR` takes precedence over `$VISUAL`, which in turn takes precedence over `$EDITOR`. If none of these environment variables is set, then the editor is taken to be `open` on Windows and OS X, or `/etc/alternatives/editor` if it exists, or `emacs` otherwise.
To use Visual Studio Code on Windows, set `$JULIA_EDITOR` to `code.cmd`.


## [Parallelization](#Parallelization)


### [`JULIA_CPU_THREADS`](#JULIA_CPU_THREADS)
Overrides the global variable [`Base.Sys.CPU_THREADS`](../../base/constants/#Base.Sys.CPU_THREADS), the number of logical CPU cores available.


### [`JULIA_WORKER_TIMEOUT`](#JULIA_WORKER_TIMEOUT)
A [`Float64`](../../base/numbers/#Core.Float64) that sets the value of `Distributed.worker_timeout()` (default: `60.0`). This function gives the number of seconds a worker process will wait for a master process to establish a connection before dying.


### [`JULIA_NUM_THREADS`](#JULIA_NUM_THREADS)
An unsigned 64-bit integer (`uint64_t`) that sets the maximum number of threads available to Julia. If `$JULIA_NUM_THREADS` is not positive or is not set, or if the number of CPU threads cannot be determined through system calls, then the number of threads is set to `1`.
If `$JULIA_NUM_THREADS` is set to `auto`, then the number of threads will be set to the number of CPU threads.
`JULIA_NUM_THREADS` must be defined before starting julia; defining it in `startup.jl` is too late in the startup process.
In Julia 1.5 and above the number of threads can also be specified on startup using the `-t`/`--threads` command line argument.
The `auto` value for `$JULIA_NUM_THREADS` requires Julia 1.7 or above.


### [`JULIA_THREAD_SLEEP_THRESHOLD`](#JULIA_THREAD_SLEEP_THRESHOLD)
If set to a string that starts with the case-insensitive substring `"infinite"`, then spinning threads never sleep. Otherwise, `$JULIA_THREAD_SLEEP_THRESHOLD` is interpreted as an unsigned 64-bit integer (`uint64_t`) and gives, in nanoseconds, the amount of time after which spinning threads should sleep.


### [`JULIA_NUM_GC_THREADS`](#JULIA_NUM_GC_THREADS)
Sets the number of threads used by Garbage Collection. If unspecified is set to half of the number of worker threads.
The environment variable was added in 1.10


### [`JULIA_IMAGE_THREADS`](#JULIA_IMAGE_THREADS)
An unsigned 32-bit integer that sets the number of threads used by image compilation in this Julia process. The value of this variable may be ignored if the module is a small module. If left unspecified, the smaller of the value of [`JULIA_CPU_THREADS`](#JULIA_CPU_THREADS) or half the number of logical CPU cores is used in its place.


### [`JULIA_IMAGE_TIMINGS`](#JULIA_IMAGE_TIMINGS)
A boolean value that determines if detailed timing information is printed during during image compilation. Defaults to 0.


### [`JULIA_EXCLUSIVE`](#JULIA_EXCLUSIVE)
If set to anything besides `0`, then Julia's thread policy is consistent with running on a dedicated machine: the master thread is on proc 0, and threads are affinitized. Otherwise, Julia lets the operating system handle thread policy.


## [REPL formatting](#REPL-formatting)
Environment variables that determine how REPL output should be formatted at the terminal. Generally, these variables should be set to [ANSI terminal escape sequences](https://en.wikipedia.org/wiki/ANSI_escape_code). Julia provides a high-level interface with much of the same functionality; see the section on [The Julia REPL](../../stdlib/REPL/#The-Julia-REPL).


### [`JULIA_ERROR_COLOR`](#JULIA_ERROR_COLOR)
The formatting `Base.error_color()` (default: light red, `"\033[91m"`) that errors should have at the terminal.


### [`JULIA_WARN_COLOR`](#JULIA_WARN_COLOR)
The formatting `Base.warn_color()` (default: yellow, `"\033[93m"`) that warnings should have at the terminal.


### [`JULIA_INFO_COLOR`](#JULIA_INFO_COLOR)
The formatting `Base.info_color()` (default: cyan, `"\033[36m"`) that info should have at the terminal.


### [`JULIA_INPUT_COLOR`](#JULIA_INPUT_COLOR)
The formatting `Base.input_color()` (default: normal, `"\033[0m"`) that input should have at the terminal.


### [`JULIA_ANSWER_COLOR`](#JULIA_ANSWER_COLOR)
The formatting `Base.answer_color()` (default: normal, `"\033[0m"`) that output should have at the terminal.


## [System and Package Image Building](#System-and-Package-Image-Building)


### [`JULIA_CPU_TARGET`](#JULIA_CPU_TARGET)
Modify the target machine architecture for (pre)compiling [system](../../devdocs/sysimg/#sysimg-multi-versioning) and [package images](../../devdocs/pkgimg/#pkgimgs-multi-versioning). `JULIA_CPU_TARGET` only affects machine code image generation being output to a disk cache. Unlike the `--cpu-target`, or `-C`, [command line option](../command-line-interface/#cli), it does not influence just-in-time (JIT) code generation within a Julia session where machine code is only stored in memory.
Valid values for [`JULIA_CPU_TARGET`](#JULIA_CPU_TARGET) can be obtained by executing `julia -C help`.
Setting [`JULIA_CPU_TARGET`](#JULIA_CPU_TARGET) is important for heterogeneous compute systems where processors of distinct types or features may be present. This is commonly encountered in high performance computing (HPC) clusters since the component nodes may be using distinct processors.
The CPU target string is a list of strings separated by `;` each string starts with a CPU or architecture name and followed by an optional list of features separated by `,`. A `generic` or empty CPU name means the basic required feature set of the target ISA which is at least the architecture the C/C++ runtime is compiled with. Each string is interpreted by LLVM.
A few special features are supported:
1.  `clone_all`
    This forces the target to have all functions in sysimg cloned. When used in negative form (i.e. `-clone_all`), this disables full clone that's enabled by default for certain targets.
2.  `base([0-9]*)`


### [`JULIA_CPU_TARGET`](#JULIA_CPU_TARGET)
    This specifies the (0-based) base target index. The base target is the target that the current target is based on, i.e. the functions that are not being cloned will use the version in the base target. This option causes the base target to be fully cloned (as if `clone_all` is specified for it) if it is not the default target (0). The index can only be smaller than the current index.
3.  `opt_size`
    Optimize for size with minimum performance impact. Clang/GCC's `-Os`.
4.  `min_size`
    Optimize only for size. Clang's `-Oz`.


## [Debugging and profiling](#Debugging-and-profiling)


### [`JULIA_DEBUG`](#JULIA_DEBUG)
Enable debug logging for a file or module, see [`Logging`](../../stdlib/Logging/#man-logging) for more information.


### [`JULIA_PROFILE_PEEK_HEAP_SNAPSHOT`](#JULIA_PROFILE_PEEK_HEAP_SNAPSHOT)
Enable collecting of a heap snapshot during execution via the profiling peek mechanism. See [Triggered During Execution](../../stdlib/Profile/#Triggered-During-Execution).


### [`JULIA_TIMING_SUBSYSTEMS`](#JULIA_TIMING_SUBSYSTEMS)
Allows you to enable or disable zones for a specific Julia run. For instance, setting the variable to `+GC,-INFERENCE` will enable the `GC` zones and disable the `INFERENCE` zones. See [Dynamically Enabling and Disabling Zones](../../devdocs/external_profilers/#Dynamically-Enabling-and-Disabling-Zones).


### [`JULIA_GC_ALLOC_POOL`](#JULIA_GC_ALLOC_POOL)


### [`JULIA_GC_ALLOC_OTHER`](#JULIA_GC_ALLOC_OTHER)


### [`JULIA_GC_ALLOC_PRINT`](#JULIA_GC_ALLOC_PRINT)
If set, these environment variables take strings that optionally start with the character `'r'`, followed by a string interpolation of a colon-separated list of three signed 64-bit integers (`int64_t`). This triple of integers `a:b:c` represents the arithmetic sequence `a`, `a + b`, `a + 2*b`, ... `c`.
-   If it's the `n`th time that `jl_gc_pool_alloc()` has been called, and `n` belongs to the arithmetic sequence represented by `$JULIA_GC_ALLOC_POOL`, then garbage collection is forced.
-   If it's the `n`th time that `maybe_collect()` has been called, and `n` belongs to the arithmetic sequence represented by `$JULIA_GC_ALLOC_OTHER`, then garbage collection is forced.
-   If it's the `n`th time that `jl_gc_collect()` has been called, and `n` belongs to the arithmetic sequence represented by `$JULIA_GC_ALLOC_PRINT`, then counts for the number of calls to `jl_gc_pool_alloc()` and `maybe_collect()` are printed.
If the value of the environment variable begins with the character `'r'`, then the interval between garbage collection events is randomized.
These environment variables only have an effect if Julia was compiled with garbage-collection debugging (that is, if `WITH_GC_DEBUG_ENV` is set to `1` in the build configuration).


### [`JULIA_GC_NO_GENERATIONAL`](#JULIA_GC_NO_GENERATIONAL)
If set to anything besides `0`, then the Julia garbage collector never performs "quick sweeps" of memory.
This environment variable only has an effect if Julia was compiled with garbage-collection debugging (that is, if `WITH_GC_DEBUG_ENV` is set to `1` in the build configuration).


### [`JULIA_GC_WAIT_FOR_DEBUGGER`](#JULIA_GC_WAIT_FOR_DEBUGGER)
If set to anything besides `0`, then the Julia garbage collector will wait for a debugger to attach instead of aborting whenever there's a critical error.
This environment variable only has an effect if Julia was compiled with garbage-collection debugging (that is, if `WITH_GC_DEBUG_ENV` is set to `1` in the build configuration).


### [`ENABLE_JITPROFILING`](#ENABLE_JITPROFILING)
If set to anything besides `0`, then the compiler will create and register an event listener for just-in-time (JIT) profiling.
This environment variable only has an effect if Julia was compiled with JIT profiling support, using either
-   Intel's [VTune™ Amplifier](https://software.intel.com/en-us/vtune) (`USE_INTEL_JITEVENTS` set to `1` in the build configuration), or
-   [OProfile](https://oprofile.sourceforge.io/news/) (`USE_OPROFILE_JITEVENTS` set to `1` in the build configuration).
-   [Perf](https://perf.wiki.kernel.org) (`USE_PERF_JITEVENTS` set to `1` in the build configuration). This integration is enabled by default.


### [`ENABLE_GDBLISTENER`](#ENABLE_GDBLISTENER)
If set to anything besides `0` enables GDB registration of Julia code on release builds. On debug builds of Julia this is always enabled. Recommended to use with `-g 2`.


### [`JULIA_LLVM_ARGS`](#JULIA_LLVM_ARGS)
Arguments to be passed to the LLVM backend.


### [`JULIA_FALLBACK_REPL`](#JULIA_FALLBACK_REPL)
Forces the fallback repl instead of REPL.jl.
------------------------------------------------------------------------


# Embedding Julia · The Julia Language
Source: https://docs.julialang.org/en/v1/manual/embedding/


# [Embedding Julia](#Embedding-Julia)
As we have seen in [Calling C and Fortran Code](../calling-c-and-fortran-code/#Calling-C-and-Fortran-Code), Julia has a simple and efficient way to call functions written in C. But there are situations where the opposite is needed: calling Julia functions from C code. This can be used to integrate Julia code into a larger C/C++ project, without the need to rewrite everything in C/C++. Julia has a C API to make this possible. As almost all programming languages have some way to call C functions, the Julia C API can also be used to build further language bridges (e.g. calling Julia from Python, Rust or C#). Even though Rust and C++ can use the C embedding API directly, both have packages helping with it, for C++ [Jluna](https://github.com/Clemapfel/jluna) is useful.


## [High-Level Embedding](#High-Level-Embedding)
**Note**: This section covers embedding Julia code in C on Unix-like operating systems. For doing this on Windows, please see the section following this, [High-Level Embedding on Windows with Visual Studio](#High-Level-Embedding-on-Windows-with-Visual-Studio).
We start with a simple C program that initializes Julia and calls some Julia code:
```c
#include <julia.h>
JULIA_DEFINE_FAST_TLS // only define this once, in an executable (not in a shared library) if you want fast code.

int main(int argc, char *argv[])
{
    /* required: setup the Julia context */
    jl_init();

    /* run Julia commands */
    jl_eval_string("print(sqrt(2.0))");

    /* strongly recommended: notify Julia that the
         program is about to terminate. this allows
         Julia time to cleanup pending write requests
         and run all finalizers
    */
    jl_atexit_hook(0);
    return 0;
}
```
In order to build this program you must add the path to the Julia header to the include path and link against `libjulia`. For instance, when Julia is installed to `$JULIA_DIR`, one can compile the above test program `test.c` with `gcc` using:
```julia
gcc -o test -fPIC -I$JULIA_DIR/include/julia -L$JULIA_DIR/lib -Wl,-rpath,$JULIA_DIR/lib test.c -ljulia
```
Alternatively, look at the `embedding.c` program in the Julia source tree in the `test/embedding/` folder. The file `cli/loader_exe.c` program is another simple example of how to set `jl_options` options while linking against `libjulia`.


## [High-Level Embedding](#High-Level-Embedding)
The first thing that must be done before calling any other Julia C function is to initialize Julia. This is done by calling `jl_init`, which tries to automatically determine Julia's install location. If you need to specify a custom location, or specify which system image to load, use `jl_init_with_image` instead.
The second statement in the test program evaluates a Julia statement using a call to `jl_eval_string`.
Before the program terminates, it is strongly recommended that `jl_atexit_hook` is called. The above example program calls this just before returning from `main`.
Currently, dynamically linking with the `libjulia` shared library requires passing the `RTLD_GLOBAL` option. In Python, this looks like:
```julia
>>> julia=CDLL('./libjulia.dylib',RTLD_GLOBAL)
>>> julia.jl_init.argtypes = []
>>> julia.jl_init()
250593296
```
If the julia program needs to access symbols from the main executable, it may be necessary to add the `-Wl,--export-dynamic` linker flag at compile time on Linux in addition to the ones generated by `julia-config.jl` described below. This is not necessary when compiling a shared library.


### [Using julia-config to automatically determine build parameters](#Using-julia-config-to-automatically-determine-build-parameters)
The script `julia-config.jl` was created to aid in determining what build parameters are required by a program that uses embedded Julia. This script uses the build parameters and system configuration of the particular Julia distribution it is invoked by to export the necessary compiler flags for an embedding program to interact with that distribution. This script is located in the Julia shared data directory.


#### [Example](#Example)
```c
#include <julia.h>

int main(int argc, char *argv[])
{
    jl_init();
    (void)jl_eval_string("println(sqrt(2.0))");
    jl_atexit_hook(0);
    return 0;
}
```


#### [On the command line](#On-the-command-line)
A simple use of this script is from the command line. Assuming that `julia-config.jl` is located in `/usr/local/julia/share/julia`, it can be invoked on the command line directly and takes any combination of three flags:
```julia
/usr/local/julia/share/julia/julia-config.jl
Usage: julia-config [--cflags|--ldflags|--ldlibs]
```
If the above example source is saved in the file `embed_example.c`, then the following command will compile it into an executable program on Linux and Windows (MSYS2 environment). On macOS, substitute `clang` for `gcc`.:
```julia
/usr/local/julia/share/julia/julia-config.jl --cflags --ldflags --ldlibs | xargs gcc embed_example.c
```


#### [Use in Makefiles](#Use-in-Makefiles)
In general, embedding projects will be more complicated than the above example, and so the following allows general makefile support as well – assuming GNU make because of the use of the **shell** macro expansions. Furthermore, although `julia-config.jl` is usually in the `/usr/local` directory, if it isn't, then Julia itself can be used to find `julia-config.jl`, and the makefile can take advantage of this. The above example is extended to use a makefile:
```julia
JL_SHARE = $(shell julia -e 'print(joinpath(Sys.BINDIR, Base.DATAROOTDIR, "julia"))')
CFLAGS   += $(shell $(JL_SHARE)/julia-config.jl --cflags)
CXXFLAGS += $(shell $(JL_SHARE)/julia-config.jl --cflags)
LDFLAGS  += $(shell $(JL_SHARE)/julia-config.jl --ldflags)
LDLIBS   += $(shell $(JL_SHARE)/julia-config.jl --ldlibs)

all: embed_example
```
Now the build command is simply `make`.


## [High-Level Embedding on Windows with Visual Studio](#High-Level-Embedding-on-Windows-with-Visual-Studio)
If the `JULIA_DIR` environment variable hasn't been setup, add it using the System panel before starting Visual Studio. The `bin` folder under JULIA_DIR should be on the system PATH.
We start by opening Visual Studio and creating a new Console Application project. Open the 'stdafx.h' header file, and add the following lines at the end:
```c
#include <julia.h>
```
Then, replace the main() function in the project with this code:
```c
int main(int argc, char *argv[])
{
    /* required: setup the Julia context */
    jl_init();

    /* run Julia commands */
    jl_eval_string("print(sqrt(2.0))");

    /* strongly recommended: notify Julia that the
         program is about to terminate. this allows
         Julia time to cleanup pending write requests
         and run all finalizers
    */
    jl_atexit_hook(0);
    return 0;
}
```
The next step is to set up the project to find the Julia include files and the libraries. It's important to know whether the Julia installation is 32- or 64-bit. Remove any platform configuration that doesn't correspond to the Julia installation before proceeding.
Using the project Properties dialog, go to `C/C++` \| `General` and add `$(JULIA_DIR)\include\julia\` to the Additional Include Directories property. Then, go to the `Linker` \| `General` section and add `$(JULIA_DIR)\lib` to the Additional Library Directories property. Finally, under `Linker` \| `Input`, add `libjulia.dll.a;libopenlibm.dll.a;` to the list of libraries.


## [High-Level Embedding on Windows with Visual Studio](#High-Level-Embedding-on-Windows-with-Visual-Studio)
At this point, the project should build and run.


## [Converting Types](#Converting-Types)
Real applications will not only need to execute expressions, but also return their values to the host program. `jl_eval_string` returns a `jl_value_t*`, which is a pointer to a heap-allocated Julia object. Storing simple data types like [`Float64`](../../base/numbers/#Core.Float64) in this way is called `boxing`, and extracting the stored primitive data is called `unboxing`. Our improved sample program that calculates the square root of 2 in Julia and reads back the result in C has a body that now contains this code:
```c
jl_value_t *ret = jl_eval_string("sqrt(2.0)");

if (jl_typeis(ret, jl_float64_type)) {
    double ret_unboxed = jl_unbox_float64(ret);
    printf("sqrt(2.0) in C: %e \n", ret_unboxed);
}
else {
    printf("ERROR: unexpected return type from sqrt(::Float64)\n");
}
```
In order to check whether `ret` is of a specific Julia type, we can use the `jl_isa`, `jl_typeis`, or `jl_is_...` functions. By typing `typeof(sqrt(2.0))` into the Julia shell we can see that the return type is [`Float64`](../../base/numbers/#Core.Float64) (`double` in C). To convert the boxed Julia value into a C double the `jl_unbox_float64` function is used in the above code snippet.
Corresponding `jl_box_...` functions are used to convert the other way:
```c
jl_value_t *a = jl_box_float64(3.0);
jl_value_t *b = jl_box_float32(3.0f);
jl_value_t *c = jl_box_int32(3);
```
As we will see next, boxing is required to call Julia functions with specific arguments.


## [Calling Julia Functions](#Calling-Julia-Functions)
While `jl_eval_string` allows C to obtain the result of a Julia expression, it does not allow passing arguments computed in C to Julia. For this you will need to invoke Julia functions directly, using `jl_call`:
```c
jl_function_t *func = jl_get_function(jl_base_module, "sqrt");
jl_value_t *argument = jl_box_float64(2.0);
jl_value_t *ret = jl_call1(func, argument);
```
In the first step, a handle to the Julia function `sqrt` is retrieved by calling `jl_get_function`. The first argument passed to `jl_get_function` is a pointer to the `Base` module in which `sqrt` is defined. Then, the double value is boxed using `jl_box_float64`. Finally, in the last step, the function is called using `jl_call1`. `jl_call0`, `jl_call2`, and `jl_call3` functions also exist, to conveniently handle different numbers of arguments. To pass more arguments, use `jl_call`:
```julia
jl_value_t *jl_call(jl_function_t *f, jl_value_t **args, int32_t nargs)
```
Its second argument `args` is an array of `jl_value_t*` arguments and `nargs` is the number of arguments.
There is also an alternative, possibly simpler, way of calling Julia functions and that is via [`@cfunction`](../../base/c/#Base.@cfunction). Using `@cfunction` allows you to do the type conversions on the Julia side, which is typically easier than doing it on the C side. The `sqrt` example above would with `@cfunction` be written as:
```c
double (*sqrt_jl)(double) = jl_unbox_voidpointer(jl_eval_string("@cfunction(sqrt, Float64, (Float64,))"));
double ret = sqrt_jl(2.0);
```


## [Calling Julia Functions](#Calling-Julia-Functions)
where we first define a C callable function in Julia, extract the function pointer from it, and finally call it. In addition to simplifying type conversions by doing them in the higher-level language, calling Julia functions via `@cfunction` pointers eliminates the dynamic-dispatch overhead required by `jl_call` (for which all of the arguments are "boxed"), and should have performance equivalent to native C function pointers.


## [Memory Management](#Memory-Management)
As we have seen, Julia objects are represented in C as pointers of type `jl_value_t*`. This raises the question of who is responsible for freeing these objects.
Typically, Julia objects are freed by the garbage collector (GC), but the GC does not automatically know that we are holding a reference to a Julia value from C. This means the GC can free objects out from under you, rendering pointers invalid.
The GC will only run when new Julia objects are being allocated. Calls like `jl_box_float64` perform allocation, but allocation might also happen at any point in running Julia code.
When writing code that embeds Julia, it is generally safe to use `jl_value_t*` values in between `jl_...` calls (as GC will only get triggered by those calls). But in order to make sure that values can survive `jl_...` calls, we have to tell Julia that we still hold a reference to Julia [root](https://www.cs.purdue.edu/homes/hosking/690M/p611-fenichel.pdf) values, a process called "GC rooting". Rooting a value will ensure that the garbage collector does not accidentally identify this value as unused and free the memory backing that value. This can be done using the `JL_GC_PUSH` macros:
```c
jl_value_t *ret = jl_eval_string("sqrt(2.0)");
JL_GC_PUSH1(&ret);
// Do something with ret
JL_GC_POP();
```


## [Memory Management](#Memory-Management)
The `JL_GC_POP` call releases the references established by the previous `JL_GC_PUSH`. Note that `JL_GC_PUSH` stores references on the C stack, so it must be exactly paired with a `JL_GC_POP` before the scope is exited. That is, before the function returns, or control flow otherwise leaves the block in which the `JL_GC_PUSH` was invoked.
Several Julia values can be pushed at once using the `JL_GC_PUSH2` to `JL_GC_PUSH6` macros:
```julia
JL_GC_PUSH2(&ret1, &ret2);
// ...
JL_GC_PUSH6(&ret1, &ret2, &ret3, &ret4, &ret5, &ret6);
```
To push an array of Julia values one can use the `JL_GC_PUSHARGS` macro, which can be used as follows:
```c
jl_value_t **args;
JL_GC_PUSHARGS(args, 2); // args can now hold 2 `jl_value_t*` objects
args[0] = some_value;
args[1] = some_other_value;
// Do something with args (e.g. call jl_... functions)
JL_GC_POP();
```
Each scope must have only one call to `JL_GC_PUSH*`, and should be paired with only a single `JL_GC_POP` call. If all necessary variables you want to root cannot be pushed by a one single call to `JL_GC_PUSH*`, or if there are more than 6 variables to be pushed and using an array of arguments is not an option, then one can use inner blocks:
```c
jl_value_t *ret1 = jl_eval_string("sqrt(2.0)");
JL_GC_PUSH1(&ret1);
jl_value_t *ret2 = 0;
{
    jl_function_t *func = jl_get_function(jl_base_module, "exp");
    ret2 = jl_call1(func, ret1);
    JL_GC_PUSH1(&ret2);
    // Do something with ret2.
    JL_GC_POP();    // This pops ret2.
}
JL_GC_POP();    // This pops ret1.
```


## [Memory Management](#Memory-Management)
Note that it is not necessary to have valid `jl_value_t*` values before calling `JL_GC_PUSH*`. It is fine to have a number of them initialized to `NULL`, pass those to `JL_GC_PUSH*` and then create the actual Julia values. For example:
```julia
jl_value_t *ret1 = NULL, *ret2 = NULL;
JL_GC_PUSH2(&ret1, &ret2);
ret1 = jl_eval_string("sqrt(2.0)");
ret2 = jl_eval_string("sqrt(3.0)");
// Use ret1 and ret2
JL_GC_POP();
```
If it is required to hold the pointer to a variable between functions (or block scopes), then it is not possible to use `JL_GC_PUSH*`. In this case, it is necessary to create and keep a reference to the variable in the Julia global scope. One simple way to accomplish this is to use a global `IdDict` that will hold the references, avoiding deallocation by the GC. However, this method will only work properly with mutable types.
```c
// This functions shall be executed only once, during the initialization.
jl_value_t* refs = jl_eval_string("refs = IdDict()");
jl_function_t* setindex = jl_get_function(jl_base_module, "setindex!");

...

// `var` is the variable we want to protect between function calls.
jl_value_t* var = 0;

...

// `var` is a `Vector{Float64}`, which is mutable.
var = jl_eval_string("[sqrt(2.0); sqrt(4.0); sqrt(6.0)]");

// To protect `var`, add its reference to `refs`.
jl_call3(setindex, refs, var, var);
```


## [Memory Management](#Memory-Management)
If the variable is immutable, then it needs to be wrapped in an equivalent mutable container or, preferably, in a `RefValue{Any}` before it is pushed to `IdDict`. In this approach, the container has to be created or filled in via C code using, for example, the function `jl_new_struct`. If the container is created by `jl_call*`, then you will need to reload the pointer to be used in C code.
```c
// This functions shall be executed only once, during the initialization.
jl_value_t* refs = jl_eval_string("refs = IdDict()");
jl_function_t* setindex = jl_get_function(jl_base_module, "setindex!");
jl_datatype_t* reft = (jl_datatype_t*)jl_eval_string("Base.RefValue{Any}");

...

// `var` is the variable we want to protect between function calls.
jl_value_t* var = 0;

...

// `var` is a `Float64`, which is immutable.
var = jl_eval_string("sqrt(2.0)");

// Protect `var` until we add its reference to `refs`.
JL_GC_PUSH1(&var);

// Wrap `var` in `RefValue{Any}` and push to `refs` to protect it.
jl_value_t* rvar = jl_new_struct(reft, var);
JL_GC_POP();

jl_call3(setindex, refs, rvar, rvar);
```
The GC can be allowed to deallocate a variable by removing the reference to it from `refs` using the function `delete!`, provided that no other reference to the variable is kept anywhere:
```c
jl_function_t* delete = jl_get_function(jl_base_module, "delete!");
jl_call2(delete, refs, rvar);
```


## [Memory Management](#Memory-Management)
As an alternative for very simple cases, it is possible to just create a global container of type `Vector{Any}` and fetch the elements from that when necessary, or even to create one global variable per pointer using
```c
jl_module_t *mod = jl_main_module;
jl_sym_t *var = jl_symbol("var");
jl_binding_t *bp = jl_get_binding_wr(mod, var, 1);
jl_checked_assignment(bp, mod, var, val);
```


### [Updating fields of GC-managed objects](#Updating-fields-of-GC-managed-objects)
The garbage collector also operates under the assumption that it is aware of every older-generation object pointing to a younger-generation one. Any time a pointer is updated breaking that assumption, it must be signaled to the collector with the `jl_gc_wb` (write barrier) function like so:
```c
jl_value_t *parent = some_old_value, *child = some_young_value;
((some_specific_type*)parent)->field = child;
jl_gc_wb(parent, child);
```
It is in general impossible to predict which values will be old at runtime, so the write barrier must be inserted after all explicit stores. One notable exception is if the `parent` object has just been allocated and no garbage collection has run since then. Note that most `jl_...` functions can sometimes invoke garbage collection.
The write barrier is also necessary for arrays of pointers when updating their data directly. Calling `jl_array_ptr_set` is usually much preferred. But direct updates can be done. For example:
```c
jl_array_t *some_array = ...; // e.g. a Vector{Any}
void **data = jl_array_data(some_array, void*);
jl_value_t *some_value = ...;
data[0] = some_value;
jl_gc_wb(jl_array_owner(some_array), some_value);
```


### [Controlling the Garbage Collector](#Controlling-the-Garbage-Collector)
There are some functions to control the GC. In normal use cases, these should not be necessary.
| Function             | Description                                  |
|:---------------------|:---------------------------------------------|
| `jl_gc_collect()`    | Force a GC run                               |
| `jl_gc_enable(0)`    | Disable the GC, return previous state as int |
| `jl_gc_enable(1)`    | Enable the GC, return previous state as int  |
| `jl_gc_is_enabled()` | Return current state as int                  |


## [Working with Arrays](#Working-with-Arrays)
Julia and C can share array data without copying. The next example will show how this works.
Julia arrays are represented in C by the datatype `jl_array_t*`. Basically, `jl_array_t` is a struct that contains:
-   Information about the datatype
-   A pointer to the data block
-   Information about the sizes of the array
To keep things simple, we start with a 1D array. Creating an array containing Float64 elements of length 10 can be done like this:
```c
jl_value_t* array_type = jl_apply_array_type((jl_value_t*)jl_float64_type, 1);
jl_array_t* x          = jl_alloc_array_1d(array_type, 10);
```
Alternatively, if you have already allocated the array you can generate a thin wrapper around its data:
```c
double *existingArray = (double*)malloc(sizeof(double)*10);
jl_array_t *x = jl_ptr_to_array_1d(array_type, existingArray, 10, 0);
```
The last argument is a boolean indicating whether Julia should take ownership of the data. If this argument is non-zero, the GC will call `free` on the data pointer when the array is no longer referenced.
In order to access the data of `x`, we can use `jl_array_data`:
```c
double *xData = jl_array_data(x, double);
```
Now we can fill the array:
```c
for (size_t i = 0; i < jl_array_nrows(x); i++)
    xData[i] = i;
```
Now let us call a Julia function that performs an in-place operation on `x`:
```c
jl_function_t *func = jl_get_function(jl_base_module, "reverse!");
jl_call1(func, (jl_value_t*)x);
```
By printing the array, one can verify that the elements of `x` are now reversed.


### [Accessing Returned Arrays](#Accessing-Returned-Arrays)
If a Julia function returns an array, the return value of `jl_eval_string` and `jl_call` can be cast to a `jl_array_t*`:
```c
jl_function_t *func  = jl_get_function(jl_base_module, "reverse");
jl_array_t *y = (jl_array_t*)jl_call1(func, (jl_value_t*)x);
```
Now the content of `y` can be accessed as before using `jl_array_data`. As always, be sure to keep a reference to the array while it is in use.


### [Multidimensional Arrays](#Multidimensional-Arrays)
Julia's multidimensional arrays are stored in memory in column-major order. Here is some code that creates a 2D array and accesses its properties:
```c
// Create 2D array of float64 type
jl_value_t *array_type = jl_apply_array_type((jl_value_t*)jl_float64_type, 2);
int dims[] = {10,5};
jl_array_t *x  = jl_alloc_array_nd(array_type, dims, 2);

// Get array pointer
double *p = jl_array_data(x, double);
// Get number of dimensions
int ndims = jl_array_ndims(x);
// Get the size of the i-th dim
size_t size0 = jl_array_dim(x,0);
size_t size1 = jl_array_dim(x,1);

// Fill array with data
for(size_t i=0; i<size1; i++)
    for(size_t j=0; j<size0; j++)
        p[j + size0*i] = i + j;
```
Notice that while Julia arrays use 1-based indexing, the C API uses 0-based indexing (for example in calling `jl_array_dim`) in order to read as idiomatic C code.


## [Exceptions](#Exceptions)
Julia code can throw exceptions. For example, consider:
```c
jl_eval_string("this_function_does_not_exist()");
```
This call will appear to do nothing. However, it is possible to check whether an exception was thrown:
```c
if (jl_exception_occurred())
    printf("%s \n", jl_typeof_str(jl_exception_occurred()));
```
If you are using the Julia C API from a language that supports exceptions (e.g. Python, C#, C++), it makes sense to wrap each call into `libjulia` with a function that checks whether an exception was thrown, and then rethrows the exception in the host language.


### [Throwing Julia Exceptions](#Throwing-Julia-Exceptions)
When writing Julia callable functions, it might be necessary to validate arguments and throw exceptions to indicate errors. A typical type check looks like:
```c
if (!jl_typeis(val, jl_float64_type)) {
    jl_type_error(function_name, (jl_value_t*)jl_float64_type, val);
}
```
General exceptions can be raised using the functions:
```c
void jl_error(const char *str);
void jl_errorf(const char *fmt, ...);
```
`jl_error` takes a C string, and `jl_errorf` is called like `printf`:
```c
jl_errorf("argument x = %d is too large", x);
```
where in this example `x` is assumed to be an integer.


### [Thread-safety](#Thread-safety)
In general, the Julia C API is not fully thread-safe. When embedding Julia in a multi-threaded application care needs to be taken not to violate the following restrictions:
-   `jl_init()` may only be called once in the application life-time. The same applies to `jl_atexit_hook()`, and it may only be called after `jl_init()`.
-   `jl_...()` API functions may only be called from the thread in which `jl_init()` was called, *or from threads started by the Julia runtime*. Calling Julia API functions from user-started threads is not supported, and may lead to undefined behaviour and crashes.
The second condition above implies that you can not safely call `jl_...()` functions from threads that were not started by Julia (the thread calling `jl_init()` being the exception). For example, the following is not supported and will most likely segfault:
```c
void *func(void*)
{
    // Wrong, jl_eval_string() called from thread that was not started by Julia
    jl_eval_string("println(Threads.threadid())");
    return NULL;
}

int main()
{
    pthread_t t;

    jl_init();

    // Start a new thread
    pthread_create(&t, NULL, func, NULL);
    pthread_join(t, NULL);

    jl_atexit_hook(0);
}
```
Instead, performing all Julia calls from the same user-created thread will work:


### [Thread-safety](#Thread-safety)
```c
void *func(void*)
{
    // Okay, all jl_...() calls from the same thread,
    // even though it is not the main application thread
    jl_init();
    jl_eval_string("println(Threads.threadid())");
    jl_atexit_hook(0);
    return NULL;
}

int main()
{
    pthread_t t;
    // Create a new thread, which runs func()
    pthread_create(&t, NULL, func, NULL);
    pthread_join(t, NULL);
}
```
An example of calling the Julia C API from a thread started by Julia itself:
```c
#include <julia/julia.h>
JULIA_DEFINE_FAST_TLS

double c_func(int i)
{
    printf("[C %08x] i = %d\n", pthread_self(), i);

    // Call the Julia sqrt() function to compute the square root of i, and return it
    jl_function_t *sqrt = jl_get_function(jl_base_module, "sqrt");
    jl_value_t* arg = jl_box_int32(i);
    double ret = jl_unbox_float64(jl_call1(sqrt, arg));

    return ret;
}

int main()
{
    jl_init();

    // Define a Julia function func() that calls our c_func() defined in C above
    jl_eval_string("func(i) = ccall(:c_func, Float64, (Int32,), i)");

    // Call func() multiple times, using multiple threads to do so
    jl_eval_string("println(Threads.threadpoolsize())");
    jl_eval_string("use(i) = println(\"[J $(Threads.threadid())] i = $(i) -> $(func(i))\")");
    jl_eval_string("Threads.@threads for i in 1:5 use(i) end");

    jl_atexit_hook(0);
}
```
If we run this code with 2 Julia threads we get the following output (note: the output will vary per run and system):


### [Thread-safety](#Thread-safety)
```sh
$ JULIA_NUM_THREADS=2 ./thread_example
2
[C 3bfd9c00] i = 1
[C 23938640] i = 4
[J 1] i = 1 -> 1.0
[C 3bfd9c00] i = 2
[J 1] i = 2 -> 1.4142135623730951
[C 3bfd9c00] i = 3
[J 2] i = 4 -> 2.0
[C 23938640] i = 5
[J 1] i = 3 -> 1.7320508075688772
[J 2] i = 5 -> 2.23606797749979
```
As can be seen, Julia thread 1 corresponds to pthread ID 3bfd9c00, and Julia thread 2 corresponds to ID 23938640, showing that indeed multiple threads are used at the C level, and that we can safely call Julia C API routines from those threads.
------------------------------------------------------------------------


# Code Loading · The Julia Language
Source: https://docs.julialang.org/en/v1/manual/code-loading/


# [Code Loading](#code-loading)
This chapter covers the technical details of package loading. To install packages, use [`Pkg`](../../stdlib/Pkg/#Pkg), Julia's built-in package manager, to add packages to your active environment. To use packages already in your active environment, write `import X` or `using X`, as described in the [Modules documentation](../modules/#modules).


## [Definitions](#Definitions)
Julia has two mechanisms for loading code:
1.  **Code inclusion:** e.g. `include("source.jl")`. Inclusion allows you to split a single program across multiple source files. The expression `include("source.jl")` causes the contents of the file `source.jl` to be evaluated in the global scope of the module where the `include` call occurs. If `include("source.jl")` is called multiple times, `source.jl` is evaluated multiple times. The included path, `source.jl`, is interpreted relative to the file where the `include` call occurs. This makes it simple to relocate a subtree of source files. In the REPL, included paths are interpreted relative to the current working directory, [`pwd()`](../../base/file/#Base.Filesystem.pwd).
2.  **Package loading:** e.g. `import X` or `using X`. The import mechanism allows you to load a package—i.e. an independent, reusable collection of Julia code, wrapped in a module—and makes the resulting module available by the name `X` inside of the importing module. If the same `X` package is imported multiple times in the same Julia session, it is only loaded the first time—on subsequent imports, the importing module gets a reference to the same module. Note though, that `import X` can load different packages in different contexts: `X` can refer to one package named `X` in the main project but potentially to different packages also named `X` in each dependency. More on this below.


## [Definitions](#Definitions)
Code inclusion is quite straightforward and simple: it evaluates the given source file in the context of the caller. Package loading is built on top of code inclusion and serves a [different purpose](../modules/#modules). The rest of this chapter focuses on the behavior and mechanics of package loading.
A *package* is a source tree with a standard layout providing functionality that can be reused by other Julia projects. A package is loaded by `import X` or `using X` statements. These statements also make the module named `X`—which results from loading the package code—available within the module where the import statement occurs. The meaning of `X` in `import X` is context-dependent: which `X` package is loaded depends on what code the statement occurs in. Thus, handling of `import X` happens in two stages: first, it determines **what** package is defined to be `X` in this context; second, it determines **where** that particular `X` package is found.
These questions are answered by searching through the project environments listed in [`LOAD_PATH`](../../base/constants/#Base.LOAD_PATH) for project files (`Project.toml` or `JuliaProject.toml`), manifest files (`Manifest.toml` or `JuliaManifest.toml`, or the same names suffixed by `-v{major}.{minor}.toml` for specific versions), or folders of source files.


## [Federation of packages](#Federation-of-packages)
Most of the time, a package is uniquely identifiable simply from its name. However, sometimes a project might encounter a situation where it needs to use two different packages that share the same name. While you might be able fix this by renaming one of the packages, being forced to do so can be highly disruptive in a large, shared code base. Instead, Julia's code loading mechanism allows the same package name to refer to different packages in different components of an application.
Julia supports federated package management, which means that multiple independent parties can maintain both public and private packages and registries of packages, and that projects can depend on a mix of public and private packages from different registries. Packages from various registries are installed and managed using a common set of tools and workflows. The `Pkg` package manager that ships with Julia lets you install and manage your projects' dependencies. It assists in creating and manipulating project files (which describe what other projects that your project depends on), and manifest files (which snapshot exact versions of your project's complete dependency graph).


## [Federation of packages](#Federation-of-packages)
One consequence of federation is that there cannot be a central authority for package naming. Different entities may use the same name to refer to unrelated packages. This possibility is unavoidable since these entities do not coordinate and may not even know about each other. Because of the lack of a central naming authority, a single project may end up depending on different packages that have the same name. Julia's package loading mechanism does not require package names to be globally unique, even within the dependency graph of a single project. Instead, packages are identified by [universally unique identifiers](https://en.wikipedia.org/wiki/Universally_unique_identifier) (UUIDs), which get assigned when each package is created. Usually you won't have to work directly with these somewhat cumbersome 128-bit identifiers since `Pkg` will take care of generating and tracking them for you. However, these UUIDs provide the definitive answer to the question of *"what package does `X` refer to?"*


## [Federation of packages](#Federation-of-packages)
Since the decentralized naming problem is somewhat abstract, it may help to walk through a concrete scenario to understand the issue. Suppose you're developing an application called `App`, which uses two packages: `Pub` and `Priv`. `Priv` is a private package that you created, whereas `Pub` is a public package that you use but don't control. When you created `Priv`, there was no public package by the name `Priv`. Subsequently, however, an unrelated package also named `Priv` has been published and become popular. In fact, the `Pub` package has started to use it. Therefore, when you next upgrade `Pub` to get the latest bug fixes and features, `App` will end up depending on two different packages named `Priv`—through no action of yours other than upgrading. `App` has a direct dependency on your private `Priv` package, and an indirect dependency, through `Pub`, on the new public `Priv` package. Since these two `Priv` packages are different but are both required for `App` to continue working correctly, the expression `import Priv` must refer to different `Priv` packages depending on whether it occurs in `App`'s code or in `Pub`'s code. To handle this, Julia's package loading mechanism distinguishes the two `Priv` packages by their UUID and picks the correct one based on its context (the module that called `import`). How this distinction works is determined by environments, as explained in the following sections.


## [Environments](#Environments)
An *environment* determines what `import X` and `using X` mean in various code contexts and what files these statements cause to be loaded. Julia understands two kinds of environments:
1.  **A project environment** is a directory with a project file and an optional manifest file, and forms an *explicit environment*. The project file determines what the names and identities of the direct dependencies of a project are. The manifest file, if present, gives a complete dependency graph, including all direct and indirect dependencies, exact versions of each dependency, and sufficient information to locate and load the correct version.
2.  **A package directory** is a directory containing the source trees of a set of packages as subdirectories, and forms an *implicit environment*. If `X` is a subdirectory of a package directory and `X/src/X.jl` exists, then the package `X` is available in the package directory environment and `X/src/X.jl` is the source file by which it is loaded.
These can be intermixed to create **a stacked environment**: an ordered set of project environments and package directories, overlaid to make a single composite environment. The precedence and visibility rules then combine to determine which packages are available and where they get loaded from. Julia's load path forms a stacked environment, for example.
These environment each serve a different purpose:


## [Environments](#Environments)
-   Project environments provide **reproducibility**. By checking a project environment into version control—e.g. a git repository—along with the rest of the project's source code, you can reproduce the exact state of the project and all of its dependencies. The manifest file, in particular, captures the exact version of every dependency, identified by a cryptographic hash of its source tree, which makes it possible for `Pkg` to retrieve the correct versions and be sure that you are running the exact code that was recorded for all dependencies.
-   Package directories provide **convenience** when a full carefully-tracked project environment is unnecessary. They are useful when you want to put a set of packages somewhere and be able to directly use them, without needing to create a project environment for them.
-   Stacked environments allow for **adding** tools to the primary environment. You can push an environment of development tools onto the end of the stack to make them available from the REPL and scripts, but not from inside packages.
At a high-level, each environment conceptually defines three maps: roots, graph and paths. When resolving the meaning of `import X`, the roots and graph maps are used to determine the identity of `X`, while the paths map is used to locate the source code of `X`. The specific roles of the three maps are:
-   **roots:** `name::Symbol` ⟶ `uuid::UUID`


## [Environments](#Environments)
    An environment's roots map assigns package names to UUIDs for all the top-level dependencies that the environment makes available to the main project (i.e. the ones that can be loaded in `Main`). When Julia encounters `import X` in the main project, it looks up the identity of `X` as `roots[:X]`.
-   **graph:** `context::UUID` ⟶ `name::Symbol` ⟶ `uuid::UUID`
    An environment's graph is a multilevel map which assigns, for each `context` UUID, a map from names to UUIDs, similar to the roots map but specific to that `context`. When Julia sees `import X` in the code of the package whose UUID is `context`, it looks up the identity of `X` as `graph[context][:X]`. In particular, this means that `import X` can refer to different packages depending on `context`.
-   **paths:** `uuid::UUID` × `name::Symbol` ⟶ `path::String`
    The paths map assigns to each package UUID-name pair, the location of that package's entry-point source file. After the identity of `X` in `import X` has been resolved to a UUID via roots or graph (depending on whether it is loaded from the main project or a dependency), Julia determines what file to load to acquire `X` by looking up `paths[uuid,:X]` in the environment. Including this file should define a module named `X`. Once this package is loaded, any subsequent import resolving to the same `uuid` will create a new binding to the already-loaded package module.
Each kind of environment defines these three maps differently, as detailed in the following sections.


## [Environments](#Environments)
For ease of understanding, the examples throughout this chapter show full data structures for roots, graph and paths. However, Julia's package loading code does not explicitly create these. Instead, it lazily computes only as much of each structure as it needs to load a given package.