我需要为专有库编写Python2包装器,包含几个.h文件(我制作了一个大文件),一堆.dll和一个.lib文件来链接所有这些东西。
我认为我需要API级别,因为.h文件中的所有`typedef'
创建包装器的脚本:build_wrapper.py
from cffi import FFI
import setuptools
ffibuilder = FFI()
ffibuilder.set_unicode(enabled_flag=True)
with open(os.path.join(curdir, 'include', 'ScadWrapper.h'), 'r') as f:
source = f.read()
ffibuilder.set_source('_wrapper', source,
extra_link_args=[r'C:\Documents\python\pyScadApi\pyScadApi\include\SCADAPIX.lib', ],
source_extension='.cpp')
if __name__ == '__main__':
ffibuilder.compile(verbose=True)
这样运行没有错误Creating library .\Release\_wrapper.lib and object .\Release\_wrapper.exp
但是,例如,
from _wrapper import ffi, lib
lp_api = ffi.new('ScadAPI *')
r = lib.ApiCreate(lp_api)
失败
lp_api = ffi.new('ScadAPI *')
ffi.error: undefined type name
ScadAPI *
ScadAPI
定义为
struct APIHandle_tag;
typedef APIHandle_tag * ScadAPI;
在ScadWrapper.h中
答案 0 :(得分:1)
你永远不会打电话给ffibuilder.cdef()
。这就是lib
对象为空的原因:它不知道任何类型或函数。
对于简短而感到抱歉。我的观点是http://cffi.readthedocs.io/en/latest/overview.html解释了基础知识。按照“真实的例子”,我们的想法是在cdef()中只写入你感兴趣的部分,一个接一个的函数,以及适当使用...;
的类型声明。您在cdef()中编写的每个函数或类型都可用于调用(通过lib.the_function_name()
)或用于ffi操作(ffi.new()
等)。
cffi有多种不同的方法(没有直接记录或支持),它们试图一次暴露整个大型库,而不需要任何逐个功能的工作,无论多么小。我们的想法是从.h文件中提取(可能由gcc -E
预处理)cdef()可以接受的内容。缺点,特别是如果您使用gcc -E
,结果可能只适用于您的确切操作系统。此外,这种方法看起来更快但往往不是:它似乎避免了每个函数的工作,但这永远不会成立,因为如果你打算在某个地方使用该函数,那么你将花时间编写该函数调用反正。