0

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

4

1 回答 1

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,结果可能仅适用于您的确切操作系统。此外,这种方法看起来更快但通常不是:它似乎避免了每个函数的工作,但事实并非如此,因为如果您要在某个地方使用该函数,那么您将花时间编写该函数调用反正。

于 2017-01-31T10:08:58.257 回答