我在研究Julia,我正在尝试编写一个libpq(PostgreSQL C library)包装器。
函数启动PostgreSQL连接,并返回指向连接结构的指针。libpq没有公开连接结构,因为它没有用处。
当连接完成时,必须使用C函数PQconnectdb
关闭它,除其他外,该函数还负责释放结构内存。
所以我想当GC完成连接时我应该调用PQfinish
函数,这就是下面代码的目的(Julia版本:0.3.0-744~ubuntu13.10.1):
module LibPQ
typealias PGconn Ptr{Void}
function pgconn_finalizer(x::PGconn)
ccall( (:PQfinish, "libpq"), Void, (PGconn,), x )
println("finalized")
end
c = ccall( (:PQconnectdb, "libpq"), PGconn, (Ptr{Uint8},), "connection params" )
finalizer(c, pgconn_finalizer)
println(c)
gc()
end
但我有个错误:
$ julia libpq.jl
ERROR: objects of type Ptr{None} cannot be finalized
in finalizer at base.jl:103
in include at boot.jl:240
while loading ./libpq.jl, in expression starting on line 12
我想我应该为
PQfinish
类型别名使用另一种类型,但我无法确定是哪种类型。知道吗? 最佳答案
正如julia-dev mailing list post所建议的,解决方案是声明一个带有指针句柄的新类型,该指针句柄将由PQfinish
释放,如下面的代码所示:
module LibPQ
type PGconn
handle::Ptr{Void}
end
function pgconn_finalizer(c::PGconn)
if c.handle != C_NULL
ccall( (:PQfinish, "libpq"), Void, (Ptr{Void},), c.handle )
c.handle = C_NULL
end
println("finalized")
end
c = ccall( (:PQconnectdb, "libpq"), PGconn, (Ptr{Uint8},), "connection params" )
finalizer(c, pgconn_finalizer)
println(c)
gc()
end