什么是使用pointer_from_objref()和Ref()的正确方法?

时间:2015-10-07 12:40:11

标签: pointers julia

只需从doc复制:

pointer_from_objref(object_instance):

  

生成的Ptr的存在不会保护对象不被垃圾收集,因此您必须确保在使用Ptr的整个时间内对象仍然被引用。

参考{T}:

  

安全引用类型T数据的对象。此类型保证指向正确类型的有效Julia分配内存。只要引用了Ref本身,就可以保护底层数据不被垃圾收集器释放。

     

当作为ccall参数传递时(作为Ptr或Ref类型),Ref对象将被转换为指向它引用的数据的本机指针。

     

没有无效(NULL)参考。

我想传递指向c函数的指针。根据文档,似乎使用pointer_from_objref并不总是安全的,所以我尝试使用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

结果显示test 2给出意外结果而没有任何错误,但test 3在将bufferID转换为数组时效果正常。

我的问题是为什么test 2会在没有发生错误的情况下给出意外结果。为安全起见,始终使用Ref()代替pointer_from_objref()是正确的吗?如果是,是否有任何副作用(例如表现)?

我正在使用julia v"0.4.0-rc1"

1 个答案:

答案 0 :(得分:1)

查看此部分:http://docs.julialang.org/en/latest/manual/calling-c-and-fortran-code/#passing-pointers-for-modifying-inputs

要遵循该模式,请尝试以下操作,这对我的其他ccall()代码起作用。我认为Ref {T}是内存分配的重要部分,并通过var []解除引用。

# test 4
bufferID = Ref{GLuint}(0)
glGenBuffers(1, bufferID)
@show bufferID[]