There is an example in the Julia doc of constructing, destructing a GSL permutation object using ccall:
https://docs.julialang.org/en/stable/manual/calling-c-and-fortran-code/#Some-Examples-of-C-Wrappers-1
In this example, (1) it is possible to create a Julia permutation object which is not valid in a GSL call and (2) if the Julia object is garbage collected, the underlying object managed by the C library will never be freed.
For my wrapper of the CALCEPH lib, I have come up with the following RAII design using inner constructor/finalizers.
type CalcephEphem
data :: Ptr{Void}
function CalcephEphem(files::Vector{<:AbstractString})
ptr = ccall((:calceph_open_array, libcalceph), Ptr{Void}, (Int, Ptr{Ptr{UInt8}}), length(files), files)
if (ptr == C_NULL)
error("Unable to open ephemeris file(s)!")
end
obj = new(ptr)
finalizer(obj,CalcephEphemDestructor) # register object destructor
return obj
end
end
# to be called by gc when cleaning up
# not in the exposed interface but can be called with finalize(e)
function CalcephEphemDestructor(e::CalcephEphem)
if (e.data == C_NULL)
return
end
ccall((:calceph_close, libcalceph), Void, (Ptr{Void},), e.data)
e.data = C_NULL
return
end
CalcephEphem(file::AbstractString) = CalcephEphem([file])
function CalcephPrefetch(e::CalcephEphem)
if (e.data == C_NULL)
error("Ephemeris object is not propely initialized.")
end
stat = ccall((:calceph_prefetch, libcalceph), Int, (Ptr{Void},), e.data)
if (stat == 0)
error("Unable to prefetch ephemeris!")
end
return
end
export CalcephEphem, CalcephPrefetch
Is this a proper way of doing this sort of thing in Julia or should I prefer the GSL example way in the docs?
Thank you.