代码之家  ›  专栏  ›  技术社区  ›  maveme

如何使用CFFI在Python中实现C接口

  •  0
  • maveme  · 技术社区  · 5 年前

    我想知道如何使用现有的C接口(头文件),并使用CFFI库在Python中实现这样的接口。

    例如,我有以下头文件, interface.h :

    void* foo(void* value);
    

    我想用Python实现它。我以为下面的程序会做这项工作,但它没有。它创建了以下函数 foo ,但它不能保证实现遵循头文件中定义的结构。

    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)
    

    如何使用CFFI传递Python对象?

    在上述示例中,由于调用 foo 它返回一个Python对象。 然后在客户端,我有以下内容:

    ffi = FFI()
    # Load my lib file
    lib = C.CDLL(dll)
    
    h = lib.foo("math")
    

    当我查找h的值时,它显示了一个整数类型的数字。然而,我原本期待收到一件物品。根据该界面, foo 必须返回指针 void* 。我如何从中读取该对象?我做错什么了吗?

    0 回复  |  直到 5 年前
        1
  •  1
  •   Armin Rigo    5 年前

    回答您的最后一个问题:您正在使用 ctypes ,不 cffi ,在这个例子中。这些是不同的项目。这应该是显而易见的,因为 ffi 对象来自 cffi ,但在以下行中未使用。而不是 lib = C.CDLL() 我猜 C 作为别名 ctypes ,你应该打电话 lib = ffi.dlopen("...") !

        2
  •  1
  •   maveme    5 年前

    我发现问题在于从ctypes切换到CFFI加载DLL时。第一个要求定义动态库中可用的方法。 因此,添加此项可以解决问题

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