0

いくつかの cffi 定義がいくつかのプロジェクト サブディレクトリに分散しています。各 cffi ファイルは型と関数を定義し、それぞれ_<package>.pyが読み込まれるファイルにコンパイルされます。最終的なアプリケーションではffi.include()、トップ レベルのもの (再帰的ffi.include()に下位レベルのもの) を生成 _<app>.pyし、アプリケーションにロードするコンパイル ファイルを生成します。ffiファイルのロードには単一のインスタンスを使用し*.soます。_<package>.pyただし、これがスプレッドファイルをアプリケーションにロードする方法がわかりません。次のエラーが表示されます (例):

2 つの別個の FFI 定義ファイル、root/get/ffi_getA.pyおよびroot/use/ffi_useA.py

どちらの C 関数も同じライブラリの一部です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関数にアクセス/ロードする方法は?

4

1 に答える 1

0

解決

単一の ffi インスタンスから cffi インターフェイスを構築するには、すべてをルート python cdef ビルダー スクリプトから開始する必要があります。このスクリプトから ffi インスタンスがインポートされ、前のビルダー スクリプトで定義されたタイプに依存する次のビルダー スクリプトで拡張されます。等々。基本的、

foo.py で:

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

bar.py で:

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

このように、FFI インスタンスは 1 つだけです。(おそらく、定義の重複を避けるために、cffi/cdef ファイル間のいわゆる「ダイヤモンド インポート依存関係」を避ける必要があります)。

モジュール レベルで ffi インスタンスをインポートすることは、デコレータ関数が定義された型にアクセスできるようにするために重要です。(振り返ってみると、これは些細なことですが、最初はインスタンス構築レベルでインポートし、デコレーターに別のインスタンスを使用しました-これは、カスタム定義の型が必要になるまで機能しました...)。

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

于 2016-05-12T21:22:10.047 に答える