简体   繁体   English

如何在Python中实现一个C接口并使用CFFI传递对象

[英]How to implement a C interface in Python and pass objects using CFFI

I would like to know how to use an existing C interface (a header file) and implement such an interface in Python by using the CFFI library.我想知道如何使用现有的 C 接口(header 文件)并通过使用 CFFI 库在 Python 中实现这样的接口。

For example, I have the following header file, interface.h :例如,我有以下 header 文件interface.h

void* foo(void* value);

And I want to implement it in Python.我想在 Python 中实现它。 I thought the following program would do the work work, but it doesn't.我认为以下程序可以完成工作,但事实并非如此。 It creates the function foo , but it doesn't guarantee that the implementation follows the structure defined in the header file.它创建 function foo ,但不保证实现遵循 header 文件中定义的结构。

import cffi

ffibuilder = cffi.FFI()

with open('interface.h') as f:
    data = ''.join([line for line in f if not line.startswith('#')])
    ffibuilder.embedding_api(data)

ffibuilder.set_source("_lib", r'''
    #include "interface.h"
''')

ffibuilder.embedding_init_code("""
    from _lib import ffi

     #include "interface.h"

    @ffi.def_extern()
    def foo(param):
        return __import__(param)

""")

ffibuilder.compile(verbose=True)

How to pass Python objects using CFFI?如何使用 CFFI 传递 Python 对象?

In the above example, as a result of calling foo that returns a Python object.在上面的例子中,作为调用foo的结果,返回 Python object。 Then on the client-side, I have the following:然后在客户端,我有以下内容:

ffi = FFI()
# Load my lib file
lib = C.CDLL(dll)

h = lib.foo("math")

When I look up the value of h, it shows a number of type integer.当我查看 h 的值时,它显示了一个类型为 integer 的数字。 However, I was expecting to receive an object.但是,我期待收到 object。 According to the interface, foo must return a pointer void* .根据接口, foo必须返回一个指针void* How can I read that object from it?我如何从中读取 object ? Am I doing something wrong?难道我做错了什么?

To answer your last question: you are using ctypes , not cffi , in this example.要回答您的最后一个问题:在此示例中,您使用的是ctypes ,而不是cffi These are different project.这些是不同的项目。 It should be apparent because the ffi object is from cffi , but is unused in the following lines.这应该很明显,因为ffi object 来自cffi ,但在以下行中未使用。 Instead of lib = C.CDLL() with I guess C being an alias to ctypes , you should call lib = ffi.dlopen("...") !而不是lib = C.CDLL()我猜Cctypes的别名,你应该调用lib = ffi.dlopen("...")

I found that the problem is that when switching from ctypes to CFFI for loading a DLL.我发现问题在于从 ctypes 切换到 CFFI 以加载 DLL 时。 The first requires the definition of the methods that are available in the dynamic library.第一个需要定义动态库中可用的方法。 Therefore, adding this fixes the problem因此,添加这个可以解决问题

ffi.cdef("""
  void foo(void* value);
""")

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM