我有一个C源文件/头文件,它们是一个更大项目的一部分。我想将其作为一个单元进行测试,独立于实际项目。虽然可以通过创建具有不同
我认为可以使用CFFI来实现这一点。这里是一个示例C文件:
这里有一个脚本,它只是尝试编译它,以便我可以调用一些函数。
最终,我计划将此作为一组单元测试设置的一部分。例如,一个纯Python函数
上述脚本似乎有效;它可以正常运行,创建了一个
但我无法弄清如何通过CFFI实际调用C函数。我找不到
我的主要问题(即我的X问题)是:
main()
的新项目在C中实现此目的,但我希望看看是否可以使用Python(3)及其框架(例如nose)加速测试构建,使用现有的报告框架等。我认为可以使用CFFI来实现这一点。这里是一个示例C文件:
// magic.c
// Implementation of magic.
int add(int a, int b)
{
return a;
}
标题:
// magic.h
// Add two numbers (where a + b is not greater than INT_MAX).
int add(int a, int b);
这里有一个脚本,它只是尝试编译它,以便我可以调用一些函数。
# 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()
函数的任何文档,而它似乎对整个过程非常重要。概述经常提到它,但参考中没有任何出现次数。文档中确实有一个关于调用函数的部分,但它引用了一些未显示如何创建的lib
对象。如果我查看之前的示例,将从ffi.dlopen()
创建一个lib
对象,但我不知道如何将其应用于CFFI本身正在生成的内容。我的主要问题(即我的X问题)是:
- CFFI是一种在跨平台(Windows 7-10,Linux,OS X)中调用和测试C函数的合理工具吗?如果是,如何使用?
从我的当前方法(即我的Y问题)中产生的问题是:
set_source()
的文档在哪里?我怎样才能找到它所需的参数?- 如何生成包含我想要调用的函数的
lib
对象? - 这是使用CFFI调用C函数的最简单方法吗?我不特别需要或想要生成共享库或可再分配软件包;如果必须发生,那很好,但这并非必要。我还可以尝试哪些其他方法?
我的当前设置是:
- 操作系统:Windows 10
- Python版本:CPython 3.5.1 32位
- Pip版本:8.1.2
- CFFI版本:1.6.0
- C编译器:使用Visual C++ Build Tools 2015自带的编译器,详见此MSDN帖子
我正在使用来自Christoph Gohlke的仓库的CFFI和pycparser。
ffibuilder.cdef()
调用中存在一些重复;也就是说,我将声明该函数两次,并且有风险使其不同步或引入错误。您认为有减少重复的方法吗? - detlyffi.compile()
返回.pyd
文件的名称,这可以被删除,但是它生成了一堆其他编译相关的东西,这取决于编译器。你知道是否有办法通过CFFI调用直接获取到magic_tests.lib
对象吗? - detlyverify()
函数。它已经被弃用了,所以我只能绕过它进行编程。 - detly