is it a better choice to use Ref{} instead of Ptr{}?
Gnimuc opened this issue · comments
julia v0.4 is finally released, i find a major change about pointer is Ref{T}
.
it says using Ref{T}
is more safer
As a safer alternative to creating pointers (Ptr), the managed reference type Ref has been added. A Ref points to the data contained by a value in an abstract sense, and in a way that is GC-safe.
and
When passing a by-reference argument to ccall, you can declare the argument type to be Ref{T} instead of Ptr{T}, and just pass x instead of &x.
but it seems if we do not change those Ptr{T} argument types in glfunction.jl, one may face a problem when trying to use take a look at this example:Ref{}
.
# test 1
bufferID = convert(GLuint, 0)
glGenBuffers(1, pointer_from_objref(bufferID))
@show bufferID
out => bufferID = 0x00000001 # ok
# test 2
bufferID = convert(GLuint, 0)
glGenBuffers(1, Ref(bufferID))
@show bufferID
out => bufferID = 0x00000000 # unexpected result
# test 3
bufferID = GLuint[0]
glGenBuffers(1, Ref(bufferID))
@show bufferID[]
out => bufferID[] = 0x00000001 # ok
i know doing this will break some other repos(e.g. GLAbstraction.jl), i'm also not sure whether a C programmer will feel wired when using this syntax glGenBuffers(1, bufferID)
which in C is glGenBuffers(1, &bufferID)
.
test 2
that yields unexpected results because you use Ref
wrong.
It should be:
bufferID = Ref{GLuint}(0)
glGenBuffers(1, bufferID)
@show bufferID[]
Ref(...)
copies the value to another location, from what I know, so it won't mess with the immutable.
I've been thinking about this as well, but then I haven't had time to implement anything.
Since we use @generated
functions, we can emit code specialized to the arguments.
So we could do something like this:
to_gl_args(::Type{Ptr{GLFloat}) = Ref{GLFloat}
#etc...
#in the @generated function
map(to_gl_args, gl_fun_arg_types)
thank you @SimonDanisch! i misunderstood the doc, i thought Ref
is a one-to-one analogy to &
in C/C++
, which is not true. the doc about Ref()
is still missing. i've stumbled over this problem for a couple of days. i even posted a question on stackoverflow, but no one gave a reply. i don't know @generated function
stuff, it seems that both
bufferID = Ref{GLuint}(0)
glGenBuffers(1, bufferID)
@show bufferID[]
and
bufferID = 0
glGenBuffers(1, bufferID)
@show bufferID</strike>
would be OK if you reimplemented with @generated
function.
you saved my day 👍 , thanks again!
EDIT: no, the second snippet won't work, it's the same as test 2
.