我有一些cffi定义分布在几个项目子目录中--每个cffi文件定义类型和函数,每个编译成一个要加载的_<package>.py文件。在最后一个应用程序中,我ffi.include()顶级应用程序(它递归地对低级应用程序进行ffi.include() ),并生成一个要加载到应用程序中的_<app>.py文件。我使用一个ffi实例来加载*.so文件。不过,我看不出这是如何将扩展的_<package>.py文件加载到应用程序中的。我得到以下错误(示例):
两个独立的FFI定义文件,
root/get/ffi_getA.py和root/use/ffi_useA.py
libA.so说,哪个C函数都是同一个库的一部分。
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函数?
发布于 2016-05-12 21:22:10
溶液
要从单个ffi实例构建cffi接口,一切都必须从根python构建器脚本开始。从这个脚本中,ffi实例在下一个构建器脚本中导入和扩展,该脚本依赖于在上一个构建器脚本中定义的类型,依此类推。基本上,
在foo.py中:
ffi = cffi.FFI()
ffi.cdef("...")在bar.py中:
from foo import ffi
ffi.cdef("...")这样,只有一个FFI实例。(很可能,为了避免重复定义,必须避免cffi/cdef文件之间所谓的“钻石导入依赖关系”)。
在模块级别导入ffi实例对于装饰器函数访问定义的类型至关重要。(回顾性地说,这是微不足道的,但首先我在实例构造级别导入,并为装饰器使用了一个单独的实例-直到我需要自定义类型.)。
最后,在这个过程中,您不需要ffi.include(.) --“包含”是通过导入完成的。此外,由于源只在最终构建器脚本ffi.set_source(.)中生成下标中的语句必须在"if __name__==“__main__下面,在ffi.compile(.)之前。(因此,下标在本地调用时将生成源,例如用于测试目的。)
https://stackoverflow.com/questions/36942170
复制相似问题