使用Python CFFI和.lib以及一堆.dll和.h文件

时间:2017-01-30 18:51:44

标签: c++ python-2.7 python-cffi

我需要为专有库编写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中

1 个答案:

答案 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,结果可能只适用于您的确切操作系统。此外,这种方法看起来更快但往往不是:它似乎避免了每个函数的工作,但这永远不会成立,因为如果你打算在某个地方使用该函数,那么你将花时间编写该函数调用反正。