You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Commit d42bb6d updated cfunction to allow more type signatures, such as Function, which is great for callback routines in which the C caller passes through some arguments as void* through to the callback. However, the same arguments must currently be passed as Any to ccall, which is a bit counter-intuitive.
It would be nice if ccall and cfunction accepted and treated argument types in the same way.
For example, consider the following method to pass a re-entrant callback routine to the GNU libc qsort_r function. (Warning: don't try this with MacOS or BSD, where qsort_r has a different argument order in its callback.)
function qsort_r_callback{T}(a::Ptr{T}, b::Ptr{T}, f::Function)
int32(f(unsafe_ref(a), unsafe_ref(b)) ?
-1 : unsafe_ref(a) == unsafe_ref(b) ? 0 : +1)
end
function qsort_r{T}(A::Vector{T}, f::Function)
ccall(:qsort_r, Void, (Ptr{T}, Uint, Uint, Ptr{Void}, Any),
A, length(A), sizeof(T),
cfunction(qsort_r_callback, Cint, (Ptr{T}, Ptr{T}, Function)),
f)
A
end
This works great, even for anonymous functions, e.g. qsort_r([17,2,7,3,-1,14], (a,b) -> a < b). However, if you change the Any argument of ccall to the sensible-seeming Function type, it segfaults.
The text was updated successfully, but these errors were encountered:
Jeff and I agree that this is actually a mistake in the implementation of cfunction and it needs to be modified to act like ccall in this case. So the function parameter should be declared to take type Any (or Ptr{Void}). A type assertion can be used in the body of the function if desired to convert from Any (or unsafe_pointer_to_objref())
Some background: ccall defines that a the name of a type means you are passing the struct of that type by-value (although it doesn't work right now for most types). If you want a pointer to a struct, then you must pass a Ptr{Type}. Finally, if you want a jl_value_t*, then you must use Any.
Commit d42bb6d updated
cfunction
to allow more type signatures, such asFunction
, which is great for callback routines in which the C caller passes through some arguments asvoid*
through to the callback. However, the same arguments must currently be passed asAny
toccall
, which is a bit counter-intuitive.It would be nice if
ccall
andcfunction
accepted and treated argument types in the same way.For example, consider the following method to pass a re-entrant callback routine to the GNU libc
qsort_r
function. (Warning: don't try this with MacOS or BSD, whereqsort_r
has a different argument order in its callback.)This works great, even for anonymous functions, e.g.
qsort_r([17,2,7,3,-1,14], (a,b) -> a < b)
. However, if you change theAny
argument ofccall
to the sensible-seemingFunction
type, it segfaults.The text was updated successfully, but these errors were encountered: