В C/C++ мы можем сделать это:
double my_var = 4.32;
void* my_var_ptr = &my_var;
что приводит к тому, что my_var_ptr является пустым указателем, указывающим на память, в которой хранится значение 4.32.
Я пытаюсь сделать то же самое в Джулии, но сталкиваюсь с несколькими ошибками. Наивно, я попробовал это:
my_var=Cdouble(4.32)
my_var_ptr=Ptr{Cvoid}(pointer(my_var))
что не удалось с ошибкой:
ERROR: MethodError: no method matching pointer(::Float64)
Ошибка (я полагаю) связана с тем, что я пытаюсь создать указатель Cvoid из объекта Cdouble.
Любое решение по этому поводу?
Заранее спасибо!
@Locke требует дополнительного шага с созданием Ref, и тогда он работает (как указано ниже.





julia> my_var = Cdouble(4.32)
julia> my_var_ptr = Ptr{Cvoid}(pointer_from_objref(Ref(my_var)))
Ptr{Nothing} @0x00007f2a9148c6c0
pointer работает только для массивоподобных элементов
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
Однако вы должны проверить pointer_from_objref, например:
julia> pointer_from_objref(Ref(1))
Ptr{Nothing} @0x00007f2a914feb60
Но из вики...
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.
и с помощью unsafe_pointer_from_objref я могу использовать его обратно. Большое спасибо!
Я ничего не знаю о julia, но в других языках с аналогичными ограничениями приведение/преобразование одного типа указателя в другой тип указателя обычно является вариантом. Это допустимый обходной путь для Джулии?