一般的なLISP、CFFI、およびインスタンス化C構造
-
14-10-2019 - |
質問
私は、この「問題」の解決策を探して3時間、Googleに参加しています。 CFFIを使用してLISPのC構造をインスタンス化する方法を見つけようとしています。私はcに構造体を持っています:
struct cpVect{cpFloat x,y;}
簡単ですよね?この構造物に自動生成されたCFFIバインディング(Swig、私は思う)を持っています。
(cffi:defcstruct #.(chipmunk-lispify "cpVect" 'classname)
(#.(chipmunk-lispify "x" 'slotname) :double)
(#.(chipmunk-lispify "y" 'slotname) :double))
これにより、スロットを使用してstruct "vect"が生成されます:xと:yは、外国語の名が確認します(私はバインディングを生成したり、Cライブラリ(Chipmunk Physics)をプログラムしなかったことに注意してください。大丈夫)。
私ははるかに広く検索しました、そして多分それを100回見て、それを光沢にしたかもしれませんが、他の機能で使用するためにLISPでCPVectのインスタンスを作成する方法を理解することはできません。
関数に注意してください:
cpShape *cpPolyShapeNew(cpBody *body, int numVerts, cpVect *verts, cpVect offset)
cpvectだけでなく、一連のcpvectsへのポインターも受け取ります。これにより、2番目の質問になります。一連の構造体へのポインターを作成するにはどうすればよいですか?
私は行ったことがあります http://common-lisp.net/project/cffi/manual/html_node/defcstruct.html コードを試しましたが、「エラー:Unbound変数:PTR」(私はClozure CLにいます)を取得します。言うまでもなく、インスタンスではなくポインターを返すように見えます。
私はLISPに慣れていませんが、これまでのところかなり強くなっていますが、これは私がヒットした最初の本当の問題です。ありがとう!
解決
最も一般的なLISP実装では、スタック上の構造を通過させることはできません。があります FSBVライブラリ Libffiを使用してその機能を追加します。構造レイアウトを知っている場合、一連の基本的な引数として手動で分解できますが、それは明らかに脆いです。
他のヒント
これが大いに役立つかどうかはわかりませんが、シマリスのRuby FFIバインディングを見ることができます。https://github.com/shawn42/chipmunk-ffi/blob/master/lib/chipmunk-ffi/vec2.rb
Chipmunkには、FFIがそれらを使用できるように、すべてのインラインメソッド呼び出しを備えたデータセクションがあります。それらの1つはCPVと呼ばれます。 CPVは、CPVect structを作成する方法です。 Github w/ me(Shawn42)でこれについての会話を自由に起動してください。