Julia equivalent of C argument `char **attrlist[]`

This doesn’t seem right. First, it is cleaner to make the second argument Ref{Cint}. Second, the third argument should be Ref{Ptr{Ptr{UInt8}}}, and you should definitely not pass in a Vector (a Julia-allocated) array. The reason is that the attrlist is allocated by the C function, not by Julia — it is documented as an output parameter.

Instead, you probably want something like:

# to do: more descriptive errors
function mtk_checkstatus(status::Integer)
    status != 0 && error("MTK error $status")
end

function MtkFileAttrList(filename::AbstractString)
    num_attrs = Ref{Cint}()
    attrlist = Ref{Ptr{Ptr{UInt8}}()
    status = @ccall mtklib.MtkFileAttrList(filename::Cstring, num_attrs::Ref{Cint}, attrlist::Ref{Ptr{Ptr{UInt8}})::Cint
    mtk_checkstatus(status)
    julia_attrlist = [unsafe_string(unsafe_load(attrlist[], i)) for i in 1:num_attrs[]]
    status = @ccall mtklib.MtkStringListFree(num_attrs[]::Cint, attrlist::Ref{Ptr{Ptr{UInt8}}})::Cint
    mtk_checkstatus(status)
    return julia_attrlist
end

which calls MtkFileAttrList to get the attribute list, then converts it into a native Julia array of strings, then frees the char ** with MtkStringListFree, and finally returns the native Julia array.

ccall((:MtkFileAttrList, mtklib), Cint, (C

5 Likes