# \[ANN\] CClosure.jl: C closures like what C does

**URL:** <https://discourse.julialang.org/t/ann-cclosure-jl-c-closures-like-what-c-does/81234>\
**Category:** Package Announcements\
**Tags:** package, announcement, c, closure\
**Created:** [May 18, 2022, 6:16am UTC](https://discourse.julialang.org/t/ann-cclosure-jl-c-closures-like-what-c-does/81234 "2022-05-18T06:16:11Z")\
**Posts on this page:** 1\
**Page:** 1

<div class="post-metadata">

**Author:** ![melonedo](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/melonedo/32/15503_2.png) [@melonedo](https://discourse.julialang.org/u/melonedo)\
**Post date:** [May 18, 2022, 6:16am UTC](https://discourse.julialang.org/t/ann-cclosure-jl-c-closures-like-what-c-does/81234/1 "2022-05-18T06:16:11Z")

</div>

Julia has a very powerful `@cfunction` macro that can make any pure Julia function callable to C. However, it only produces a single function pointer, contrary to modern C libraries where a pair of function pointer and a pass-through context pointer is passed to support arbitrary closures. As a result, `@cfunction`’s support for closures resorts to LLVM trampolines which is not available on all platforms.

CClosure.jl exports `cclosure`

```julia
cclosure(callable, context_position, ReturnType, (ArgumentTypes...)) -> func_ptr, context

```

which

- is regular Julia function call, so local variable and expressions are supported.
- uses the context pointer to support closures on all platforms that Julia runs.
- has no extra cost compared to `@cfunction` AFAICT.

This is an example that uses `qsort` on Windows

```julia
using CClosure
function qsort_c(a, func, ctx)
    @ccall qsort_s(a::Ptr{Cvoid}, length(a)::Csize_t, sizeof(eltype(a))::Csize_t, func::Ptr{Cvoid}, ctx::Ptr{Cvoid})::Cvoid
end
compare(a, b)::Cint = a > b ? +1 : a < b ? -1 : 0
function qsort_log_cclosure(a)
    T = eltype(a)
    log = Tuple{T, T}[]
    func, ctx = cclosure(1, Cint, (Ref{T}, Ref{T})) do a, b
        push!(log, (a, b))
        compare(a, b)
    end
    qsort_c(a, func, ctx)
    log, a
end
qsort_log_cclosure([3,2,1])

```

For more descriptions check GitHub repo: [melonedo/CClosure.jl](https://github.com/melonedo/CClosure.jl)
