Home > Net >  Cast a variable to void pointer in Julia
Cast a variable to void pointer in Julia

Time:03-21

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.

  • Related