JuliaLang/julia — pull request #1208 by vtjnash (2012-08-24 17:09:56+00:00)
Title: [RFC] c callbacks from Julia (proof-of-concept)

reference issue #1096

This is a proof-of-concept showing a more complete interop between Julia and C code, allowing the creation of Julia callbacks that can be passed to arbitrary C code. There are several optimizations that can be made (i.e. I would like to make this an intrinsic so that it doesn't have to generate code at run-time), but the intended interface would be the same.

Here's some example code that I've been using for testing:
```julia
ccallback(f::Function,t::Type,a::Tuple) = ccall(:ccallback, Ptr{Void}, (Function,Type,Tuple,Ptr{Void}), f, t, a, C_NULL)

f64 = ccall(:ccallback, Ptr{Void}, (Function,Type,Tuple,Nothing), float64, Float64, (Int,), nothing)
ccall(f64, Float64, (Int,), 1)

sh = ccall(:ccallback, Ptr{Void}, (Function,Type,Tuple,Nothing), show, Any, (Int,), nothing)
ccall(sh, Nothing, (Int,), 1)

sorti(a,b) = (ai = arrayref(a,1); bi = arrayref(b,1); println("$a $ai ? $b $bi"); bi- ai)
sorti(a,b) = (b[] - a[])
qsort{T}(a::Vector{T}, f::Function) = ccall(:qsort, Void, (Ptr{T}, Int, Int, Ptr{Void}), a, length(a), sizeof(T), ccallback(f, Int32, (Ptr{T},Ptr{T})))
x = [3,12,5,25,2]
qsort(x,sorti)

add_one = ccall(:ccallback, Ptr{Void}, (Function,Type,Tuple,Nothing), square, Int, (Int,), nothing)
x = ccall(:compute_something, Uint, (Ptr{Void},), add_one)
# in C
#extern "C" DLLEXPORT long compute_something(long (*x)(long)) {
# return x(-2)+1;
#}
```

Note that the garbage collector is not fully aware of the operation of these callbacks. Do not allow a julia object parameter to go out of scope.