日時計 CVODEライブラリの CFFI ラッパーを作成しようとしています。SWIG は Sundials のヘッダーがかなり相互接続されており、SWIG が適切なヘッダーを見つけられなかったため、窒息していました。
今、私はそれが正しく動作するかどうかをテストしようとしています. 今のところ、単に「問題オブジェクト」を作成して削除するだけです。そこから問題が始まります。したがって、「問題オブジェクト」は関数を介して割り当てられます
SUNDIALS_EXPORT void *CVodeCreate(int lmm, int iter);
ラッパーを作成したのは次のとおりです。
(cffi:defcfun "CVodeCreate" :pointer
(lmm :int)
(iter :int))
PS。SUNDIALS_EXPORT
(少なくともUnixでは)基本的に何もありません。
ここで、オブジェクトを破壊するために、Sundials は独自の関数を使用します。
SUNDIALS_EXPORT void CVodeFree(void **cvode_mem);
そのため、 によって作成されたオブジェクトへの参照を渡す必要がありますCVodeCreate
。Cでは、私の記憶に問題がなければ、次のようなことをしたでしょうCVodeFree(&problem_object)
。CL では、この関数のラッパーを作成しました。
(cffi:defcfun "CVodeFree" :void
(cvode-mem :pointer))
したがって、ここCOVDE-MEM
にポインターへのポインターがあります。質問は、CL/CFFI でポインターのポインターを取得する方法ですか? コードの冒頭は次のとおりです。
(defvar *p* (cvodecreate 1 2))
(PS. に渡される数値について心配する必要はありません。CVODECREATE
どのメソッドを使用するかを示すだけであり、読みやすくするために定数を定義する必要があります)
のよう*P*
なものです
#.(SB-SYS:INT-SAP #X7FFFE0007060)
に直接渡すとCVODEFREE
、エラーになります。
CL-USER> (cvodefree *p*)
; Evaluation aborted on #<SIMPLE-ERROR "bus error at #X~X" {1005EC9BD3}>.
渡そうとしまし(CFFI:POINTER-ADDRESS *P*)
たが、同様の「バスエラー...」が発生します(この関数が必要なものを返すかどうかさえわかりません)。私もやろうとしましたが(CFFI:MAKE-POINTER (CFFI:POINTER-ADDRESS *P*))
、もう一度成功しませんでした。
この質問は、次のアプローチを提案しています。
(cffi:with-foreign-object (p :pointer)
(setf (cffi:mem-ref p :pointer) (cvodecreate 1 2))
(cvodefree p))
これは機能します (少なくともエラーは発生しません)。私はそれがどのように機能するかを理解していると思います:それは、ポインタへのポインタを作成します(メモリを割り当てP
ます)。最後に、このポインタからポインタへのポインタを に渡します。これはまさにこれを期待しています。最後に、フォームが終了すると、割り当てられたメモリが解放されます。これは正しいアプローチですか?そして、それは私が取ることができる唯一のものですか?MEM-REF
*p
CVODECREATE
CVODEFREE
P