首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何使用CFFI调用给定源代码的现有C函数?

如何使用CFFI调用给定源代码的现有C函数?
EN

Stack Overflow用户
提问于 2016-06-21 05:11:23
回答 1查看 4.5K关注 0票数 12

我有一个C源文件/头文件,它是一个更大的项目的一部分。我想测试这作为一个单位,独立于真正的项目。虽然在C中可以通过使用不同的main()创建一个新项目来实现这一点,但我想看看是否可以使用Python (3)及其框架(例如。加快测试的构建,使用现有的报告框架等。

我当时的印象是我可以用CFFI来做这件事。下面是一个示例C文件:

代码语言:javascript
复制
// magic.c
// Implementation of magic.
int add(int a, int b)
{
    return a;
}

标题:

代码语言:javascript
复制
// magic.h
// Add two numbers (where a + b is not greater than INT_MAX).
int add(int a, int b);

下面是一个脚本,它试图编译它,这样我就可以调用一些函数:

代码语言:javascript
复制
# cffi_test.py
import cffi

INCLUDE_DIRS = ('.',)

SOURCES = ('magic.c',)

ffi = cffi.FFI()

ffi.set_source(
    '_magic_tests',
    '#include "magic.h"',
    include_dirs = INCLUDE_DIRS,
    sources = SOURCES,
    libraries = [],
    )

ffi.compile()

最终,我计划在一组单元测试(如:测试)之前,将其作为设置的一部分。纯Python函数test_add()将通过在测试设置中构造的ffi对象调用和检查C函数add()的结果。

上面的脚本似乎有效;它运行时没有错误,它创建了一个_magic_tests.c文件、一个_magic_tests.cp35-win32.pyd文件和一个Release目录。我也可以没有错误的import _magic_tests

但我不知道如何通过CFFI调用C函数。我找不到set_source()函数的任何文档,而且它似乎是整个过程中不可或缺的一部分。概述经常提到它,但是参考文献包含了零次。docs do有一个关于调用函数的部分,但是它引用了一些lib对象,而没有显示它是如何创建的。如果我查看前面的示例,就会发现有一个lib对象是从ffi.dlopen()创建的,但我不知道如何将它应用于CFFI本身正在产生的东西。

我最大的问题.我的X问题是:

  • 在跨平台(Windows7-10、Linux、OS )调用和测试C函数方面,CFFI是一个合理的工具吗?如果是的话,如何使用?

我目前的做法引起的问题.我的Y问题是:

  • set_source()的文档在哪里?我怎样才能找出需要什么论据呢?
  • 如何生成包含要调用的函数的lib对象?
  • 这是使用CFFI调用C函数的最简单方法吗?我并不特别需要或希望产生一个共享库或可再发行的包;如果必须这样做,那很好,但没有必要。我还能尝试什么其他方法?

我目前的设置是:

  • 操作系统: Windows 10
  • Python:CPython 3.5.1 32位
  • 和平执行方案: 8.1.2
  • CFFI: 1.6.0
  • C编译器:VisualC++ Build Tools 2015附带的任何东西,从这个MSDN帖子链接

我正在使用来自Christoph Gohlke储存库的CFFI和and解析器。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2016-06-21 08:22:36

对于我的一个项目,我使用cffi测试我的C代码。IMHO cffi是为C代码生成python绑定的一个很好的工具,因此认为它是从python调用和测试C函数的一个合理工具。但是,您的代码只能像C代码那样跨平台,因为您必须为每个平台编译绑定。

下面,您可以找到一些参考文档,应该回答您的问题。此外,我还编写了一些示例代码来说明如何使用cffi。举个更大的例子,您可以在https://github.com/ntruessel/qcgc/tree/master/test找到我的项目。

第四个例子,build_magic_tests.py看起来如下所示:

代码语言:javascript
复制
from cffi import FFI

ffibuilder = FFI()

# For every function that you want to have a python binding,
# specify its declaration here
ffibuilder.cdef("""
    int add(int a, int b);
                """)

# Here go the sources, most likely only includes and additional functions if necessary
ffibuilder.set_source("magic_tests",
    """
    #include "magic.h"
    """, sources=["magic.c"])

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

要生成magic_tests模块,必须运行python build_magic_tests.py。生成的模块可以按如下方式导入和使用:

代码语言:javascript
复制
from magic_tests import ffi, lib

def run_add():
    assert 4 == lib.add(4, 5)
票数 14
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/37936045

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档