0

我正在研究 Julia,我正在尝试编写一个 libpq(PostgreSQL C 库)包装器。

CPQconnectdb函数启动一个 PostgreSQL 连接,并返回一个指向连接结构的指针。libpq 没有公开连接结构,因为它没有用。连接完成后,必须使用 C 函数将其关闭PQfinish,除其他外,该函数会注意释放结构内存。

所以我想我应该PQfinish在 GC 完成连接时调用该函数,这是以下代码的目的(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

我想我应该为PGconntypealias 使用另一种类型,但我不知道是哪一种。任何的想法?

4

1 回答 1

3

正如julia-dev 邮件列表帖子所建议的那样,解决方案是声明一个带有指针句柄的新类型,该指针句柄将由 释放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
于 2014-01-28T16:17:08.760 回答