【问题标题】:How to wrap a C-function with python-cffi so that pythons keyword-arguments work?如何用 python-cffi 包装 C 函数,以便 python 关键字参数起作用?
【发布时间】:2021-08-06 18:06:18
【问题描述】:

在 python-cffi 框架中使用 API mode, calling C sources instead of a compiled library 我想在 python 中使用关键字参数调用我的 c 函数。 cffi 中是否有为此的内置功能?否则我将不得不围绕我的 cffi 包装的 c 函数编写一个 python 包装器,我不想这样做,因为它看起来像一个丑陋的解决方案。

使用 python 运行这两个文件,如果 cffi 和 gcc 存在,应该可以开箱即用:“python example_extension_build.py && python test_example.py”

注意:在此示例代码中,我使用 API level, out-of-line 模式代替(用于 clearnes)

# file: example_extension_build.py
from cffi import FFI
ffibuilder = FFI()

# objects shared between c and python
ffibuilder.cdef("""
    struct my_s{ int a; char * b; };
    int my_f(int, struct my_s);
""")

# definitions of the python-c shared objects
ffibuilder.set_source("_example",r"""

    struct my_s{ int a; char * b; };

    #include <stdio.h>
    int my_f(int arg_1, struct my_s arg_2) // some random example function
    {
        printf("%s\n", arg_2.b); 
        return arg_1 + arg_2.a;
    }

""", sources=[])

if __name__ == "__main__" :
    ffibuilder.compile(verbose=True)

python 调用

# file: test_example.py
import _example as e

n = 21;

s = e.ffi.new("struct my_s *")
s.a = 21
s.b = e.ffi.new("char[]", b"Hello World!")

# e.lib.my_f(arg_2=s[0], arg_1=n); # <-- Here is what I want
e.lib.my_f(n, s[0]); # the standard way

【问题讨论】:

    标签: python c wrapper keyword-argument python-cffi


    【解决方案1】:

    截至今天 - 2021 年 5 月 18 日 - 无法使用 cffi 包装 c 函数以向 python 公开关键字参数。此答案由 Armin Rigo 在 cffi 邮件列表 here 上提供(如果满足某些条件,Armin Rigo 将接受提供此功能的补丁)。那么唯一可能的解决方案是将 cffi 包装的 c 函数包装在 python 代码中(呃)。

    注意:如果想为 arg_2 设置默认参数值,它会变得更丑

    # file: test_wrap.py
    import _example as e
    
    def my_f(arg_1, arg_2) :
        return e.lib.my_f(arg_1, arg_2)
    
    n = 21
    
    s = e.ffi.new("struct my_s *")
    s.a = 21
    s.b = e.ffi.new("char[]", b"Hello World!")
    
    sol = my_f(arg_2=s[0], arg_1=n) # <-- Here is what I want
    
    print(sol)
    

    在命令行上

    $ python test_wrap.py
    Hello World!
    42
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2016-12-23
      • 2017-04-20
      • 2019-07-11
      • 2020-09-13
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多