In C/C we are able to do this:
double my_var = 4.32;
void* my_var_ptr = &my_var;
which results in the my_var_ptr
being a void pointer pointing to the memory which stores the value 4.32
.
I am trying to do the same in Julia, but I face several errors. Naively, I tried this:
my_var=Cdouble(4.32)
my_var_ptr=Ptr{Cvoid}(pointer(my_var))
which failed with the error:
ERROR: MethodError: no method matching pointer(::Float64)
The failure (I assume) is because I am trying to create a Cvoid
pointer from Cdouble
object.
Any solution on that?
Thanks in advance!
CodePudding user response:
TL; DR
julia> my_var = Cdouble(4.32)
julia> my_var_ptr = Ptr{Cvoid}(pointer_from_objref(Ref(my_var)))
Ptr{Nothing} @0x00007f2a9148c6c0
pointer
only works for array-like elements
julia> methods(pointer)
# 18 methods for generic function "pointer":
[1] pointer(a::Random.UnsafeView) in Random at /usr/share/julia/stdlib/v1.7/Random/src/RNGs.jl:516
[2] pointer(x::SuiteSparse.CHOLMOD.Sparse{Tv}) where Tv in SuiteSparse.CHOLMOD at /usr/share/julia/stdlib/v1.7/SuiteSparse/src/cholmod.jl:359
[3] pointer(x::SuiteSparse.CHOLMOD.Dense{Tv}) where Tv in SuiteSparse.CHOLMOD at /usr/share/julia/stdlib/v1.7/SuiteSparse/src/cholmod.jl:358
[4] pointer(x::SuiteSparse.CHOLMOD.Factor{Tv}) where Tv in SuiteSparse.CHOLMOD at /usr/share/julia/stdlib/v1.7/SuiteSparse/src/cholmod.jl:360
[5] pointer(V::SubArray{T, N, P, I, true} where {T, N, P, I<:Union{Tuple{Vararg{Real}}, Tuple{AbstractUnitRange, Vararg{Any}}}}, i::Int64) in Base at subarray.jl:431
[6] pointer(V::SubArray{T, N, P, I, true} where {T, N, P, I}, i::Int64) in Base at subarray.jl:430
[7] pointer(V::SubArray{<:Any, <:Any, <:Array, <:Tuple{Vararg{Union{Int64, AbstractRange{Int64}}}}}, is::Base.AbstractCartesianIndex{N}) where N in Base at subarray.jl:433
[8] pointer(V::SubArray{<:Any, <:Any, <:Array, <:Tuple{Vararg{Union{Int64, AbstractRange{Int64}}}}}, is::Tuple) in Base at deprecated.jl:212
[9] pointer(A::PermutedDimsArray, i::Integer) in Base.PermutedDimsArrays at permuteddimsarray.jl:61
[10] pointer(x::AbstractArray{T}) where T in Base at abstractarray.jl:1164
[11] pointer(x::AbstractArray{T}, i::Integer) where T in Base at abstractarray.jl:1165
[12] pointer(p::Cstring) in Base at c.jl:186
[13] pointer(buffer::Base64.Buffer) in Base64 at /usr/share/julia/stdlib/v1.7/Base64/src/buffer.jl:20
[14] pointer(x::SubString{String}) in Base at strings/substring.jl:122
[15] pointer(x::SubString{String}, i::Integer) in Base at strings/substring.jl:123
[16] pointer(p::Cwstring) in Base at c.jl:187
[17] pointer(s::String) in Base at strings/string.jl:95
[18] pointer(s::String, i::Integer) in Base at strings/string.jl:96
However, you should check pointer_from_objref
, for example:
julia> pointer_from_objref(Ref(1))
Ptr{Nothing} @0x00007f2a914feb60
But from the wiki...
Get the memory address of a Julia object as a Ptr. The existence of the resulting Ptr will not protect the object from garbage collection, so you must ensure that the object remains referenced for the whole time that the Ptr will be used.
This function may not be called on immutable objects, since they do not have stable memory addresses.
See also
unsafe_pointer_from_objref
.