module JModel
mutable struct JStruct
path::String
# other fields
end
jstruct = JStruct("")
Base.@ccallable function init_model(conf_path::Cstring)::Cint
global jstruct
jstruct = JStruct(unsafe_string(conf_path))
return 0
end
Base.@ccallable function proc(evt::Ptr{Culong} )::Cint
println("jstruct: ", jstruct.path)
println("evt: $(unsafe_load(evt,1))")
return 0
end
end # module JModel
Say I have to init a Julia struct from C passed in string and do a frequent proc
call from C. Does using something like this global variable have a performance cost ? What’ s the Idiom way of doing something like this?
One important point to avoid issues is to either make the global const
or add a type binding to it.
Here we use a const jstruct
and we just mutate the field since your struct is mutable. The const
just means we cannot assign a new value to jstruct
. An important consequence for this for the compiler is that we know that the type of jstruct
will not change. We can assume it will be of type JStruct
.
const jstruct = JStruct("")
Base.@ccallable function init_model(conf_path::Cstring)::Cint
global jstruct
jstruct.path = unsafe_string(conf_path)
return 0
end
Another way to do this is to add a type binding.
jstruct::JStruct = JStruct("")
Base.@ccallable function init_model(conf_path::Cstring)::Cint
global jstruct
jstruct = JStruct(unsafe_string(conf_path))
return 0
end
You could use a Ref
.
const jstruct_ref = Ref(JStruct(""))
Base.@ccallable function init_model(conf_path::Cstring)::Cint
global jstruct
jstruct[] = JStruct(unsafe_string(conf_path))
return 0
end
Base.@ccallable function proc(evt::Ptr{Culong} )::Cint
println("jstruct: ", jstruct[].path)
println("evt: $(unsafe_load(evt,1))")
return 0
end
1 Like