For working with tools around libcairo (and other gui stuff) it’s necessary to provide callback functions in C-API. I’m looking at a strange problem in front-porting from 0.6 to 1.0.
Within the package/module (CairoScript) i have
function proto_surface_create(v::Ptr{Nothing},c::Int32,w::Float64,h::Float64,uid::UInt64)
s = CairoSurface(v)
s.ptr
end
surf_create_c = @cfunction(proto_surface_create, Ptr{Nothing},
(Ptr{Nothing},Int32,Float64,Float64,UInt64))
but, when this surf_create_c is used in testing, i get an assertion of the underlying c code that this is 0x0000
It looks like your code is not actually safe for precompilation. You can read all about it here: Modules · The Julia Language but the general idea is that there’s no guarantee that a raw pointer (like a pointer to a c function) will be valid both when the module is precompiled and later on when the module is loaded, perhaps by an entirely different Julia process.
There is an example in the manual (in the section I linked) that shows an easy way of resolving the problem by changing:
surf_create_c = @cfunction(...)
into:
const surf_create_c = Ref{Ptr{Cvoid}}(0)
function __init__()
surf_create_c[] = @cfunction(...)
end
This will cause the raw pointer to be computed when the module is loaded (i.e. when that pointer is valid) rather than when the module is precompiled. You just need to also change any usages of surf_create_c into surf_create_c[].
Note also that the cost declaration is not necessary for correctness here, but it will significantly improve the performance of any code that uses surf_create_c, since it avoids the performance penalty of non-const global variables.