2016-04-29 18 views
0

いくつかのプロジェクトサブディレクトリにいくつかのcffi定義が広がっています。それぞれのcffiファイルはタイプと関数を定義し、それぞれがロードされる_<package>.pyファイルにコンパイルされます。最終的なアプリケーションでは、ffi.include()トップレベルのもの(これは再帰的にffi.include()より低いレベルのものです)をコンパイルしてアプリケーションにロードする_<app>.pyファイルを生成します。 *.soファイルをロードするために単一のffiインスタンスを使用します。私はどのようにこれがアプリケーションにファイル_<package>.pyをロードするのかわかりません。私は次のエラー(例)を取得:ffi.include(...)を含む複数のffi定義

二つの別々のFFIの定義ファイル、Cの関数は両方とも同じライブラリーの一部でありroot/get/ffi_getA.pyroot/use/ffi_useA.py

を、libA.soを言います。

ffi_getA.py

from cffi import FFI 
ffi=FFI() 
ffi.set_source("getA",None) 
ffi.cdef(''' 
typedef ... A;  // type also used in another ffi definition. 
const A* get_A(); 
''') 

ffi_useA.py:アプリケーションで

from cffi import FFI 
ffi=FFI() 
ffi.set_source("useA",None) 
from root.get import ffi_getA 
ffi.include(ffi_getA.ffi)   # makes available type A 
ffi.cdef(''' 
const void* use_A(const A*); // use type A 
''') 

:この混合は仕事に行くのではありませんので、質問がある

from root.get import getA # compiled ffi 
from root.use import useA # compiled ffi 

libAget = getA.ffi.dlopen("libA.so") 
libAuse = useA.ffi.dlopen("libA.so") 

a = libAget.getA() 

libAuse.useA(a) # !!! mixing !!!, a is indeed of type A ... 
       # ... but from a different ffi instance. 

共通の/単一のffiオブジェクトを使用して、さまざまなコンパイル済みffiオブジェクトにまたがるcdef関数へのアクセス/ロード方法を教えてください。

+0

cffiが期待しているように見えます。しかし、あなたが見つけた解決策を共有するためにあなたの質問を編集するのではなく、別の答えとして投稿してそれを受け入れるのではなく、私たちがあなたに手伝ってもらうために具体的な例を提示する必要があります(またはcffi :-) –

+1

@stustd 。あなたはもう少しそれを説明する必要があります。 –

答えて

0

すべてがルートPythonのCDEFビルダースクリプトを起動する必要があり、単一のFFIインスタンスからcffiインターフェイスを構築するためのソリューション

。このスクリプトから、ffiインスタンスがインポートされ、前のBuilderスクリプトで定義されたタイプに依存する次のBuilderスクリプトに拡張されます。等々。基本的には、foo.pyで

:bar.pyで

ffi = cffi.FFI() 
ffi.cdef("...") 

:このように

from foo import ffi 
ffi.cdef("...") 

、一つだけFFIインスタンスがあります。 (重複する定義を避けるために、cffi/cdefファイル間のダイヤモンドインポートの依存関係を回避する必要があります)。

モジュールレベルでffiインスタンスをインポートすることは、デコレータ関数が定義された型にアクセスするために重要です。 (回顧的にはこれは簡単ですが、最初はインスタンスのコンストラクションレベルでインポートし、デコレータに別のインスタンスを使用しました。これはカスタム定義型が必要になるまで機能しました...)。

最後に、この手順ではffi.include(...)は必要ありません。「包含」はインポートによって行われます。また、ソースが最終ビルダースクリプトffi.set_source(..)でのみ生成されるため、添字の文はffi.compile(...)の前に "if __name __ ==" __ main__ "の下に移動する必要があります(したがって、ローカルで呼び出されたときにソースを生成します(例えば、テスト目的のために)。

関連する問題