0

Julia について勉強していて、libpq (PostgreSQL C ライブラリ) ラッパーを書こうとしています。

CPQconnectdb関数は PostgreSQL 接続を開始し、接続構造体へのポインターを返します。接続構造体は、役に立たないため、libpq によって公開されません。接続が終了したら、C 関数を使用して接続を閉じる必要があります。この関数PQfinishは、とりわけ、構造体メモリを解放するように注意します。

したがって、接続が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

タイプエイリアスに別のタイプを使用する必要があると思いますPGconnが、どのタイプかわかりません。何か案が?

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 に答える