%module code
%{
#include "code.h"
%}
%include "std_vector.i"
namespace std {
/* On a side note, the names VecDouble and VecVecdouble can be changed, but the order of first the inner vector matters! */
%template(VecDouble) vector<double>;
%template(VecVecdouble) vector< vector<double> >;
}
%include "code.h"
除了建议的其他答案,如果你想要一个加速器模块,你可以试试Numba . 它工作"by generating optimized machine code using the LLVM compiler infrastructure at import time, runtime, or statically (using the included pycc tool)" .
14 回答
Cython肯定是要走的路,除非你期望编写Java包装器,在这种情况下,SWIG可能更好 .
我建议使用
runcython
命令行实用程序,这使得使用Cython的过程非常简单 . 如果您需要将结构化数据传递给C,请查看Google 's protobuf library, it'非常方便 .以下是我使用这两种工具制作的最小示例:
https://github.com/nicodjimenez/python2cpp
希望它可以成为一个有用的起点 .
你应该看看Boost.Python . 以下是他们网站的简短介绍:
ctypes是标准库的一部分,因此比swig更稳定和广泛可用,它总是倾向于给我problems .
使用ctypes,你需要满足任何编译时对python的依赖,你的绑定将适用于任何具有ctypes的python,而不仅仅是它编译的那个 .
假设您想在一个名为foo.cpp的文件中与一个简单的C示例类进行对话:
由于ctypes只能与C函数通信,因此需要提供那些将它们声明为extern“C”的函数 .
接下来,您必须将其编译为共享库
最后你必须编写你的python包装器(例如在fooWrapper.py中)
一旦你有了,你可以称之为
最快的方法是使用SWIG .
SWIG tutorial中的示例:
接口文件:
在Unix上构建Python模块:
用法:
请注意,您必须拥有python-dev . 另外在某些系统中,python头文件将基于你安装它的方式在/usr/include/python2.7中 .
从教程:
我从这个页面开始我的Python < - > C绑定之旅,目的是链接高级数据类型(多维STL向量与Python列表):-)
在尝试了基于ctypes和boost.python(并且不是软件工程师)的解决方案时,我发现在需要高级数据类型绑定时它们很复杂,而我发现SWIG对于这种情况更加简单 .
这个例子因此使用了SWIG,并且已经在Linux中进行了测试(但是SWIG可用并且在Windows中也被广泛使用) .
目标是使Python可以使用C函数,该函数采用2D STL向量形式的矩阵并返回每行的平均值(作为1D STL向量) .
C(“code.cpp”)中的代码如下:
等效 Headers (“code.h”)是:
我们首先编译C代码来创建一个目标文件:
然后,我们为C函数定义SWIG interface definition file("code.i") .
使用SWIG,我们从SWIG接口定义文件生成C接口源代码 .
我们最终编译生成的C接口源文件并将所有内容链接在一起以生成可由Python直接导入的共享库(“_”事项):
我们现在可以在Python脚本中使用该函数:
查看pyrex或Cython . 它们是类似Python的语言,用于连接C / C和Python .
还有
pybind11
,它类似于Boost.Python的轻量级版本,并且与所有现代C编译器兼容:https://pybind11.readthedocs.io/en/latest/
This paper, claiming Python to be all a scientist needs,基本上说:首先用Python编写原型 . 然后,当您需要加速部分时,使用SWIG并将此部分转换为C.
我从来没有用过它,但我听说过关于ctypes的好消息 . 如果您尝试将其与C一起使用,请务必通过extern "C"来避免名称损坏 . 感谢您的评论,FlorianBösch .
我认为python的cffi可以是一个选项 .
http://cffi.readthedocs.org/en/release-0.7/
对于现代C,请使用cppyy:http://cppyy.readthedocs.io/en/latest/
它基于Cling,Clang / LLVM的C解释器 . 绑定在运行时,不需要额外的中间语言 . 感谢Clang,它支持C 17 .
使用pip安装它:
对于小型项目,只需加载相关的库和您感兴趣的 Headers . 例如 . 从ctypes中获取代码示例是这个线程,但是在头部和代码部分中分开:
编译它:
并使用它:
通过自动加载准备好的反射信息和cmake片段来支持大型项目来创建它们,以便已安装软件包的用户可以简单地运行:
借助LLVM,可以实现高级功能,例如自动模板实例化 . 继续这个例子:
注意:我是cppyy的作者 .
其中一个官方Python文档包含extending Python using C/C++的详细信息 . 即使不使用SWIG,它也非常简单,在Windows上运行得非常好 .
问题是如果我理解正确的话,如何从Python调用C函数 . 然后最好的选择是Ctypes(BTW可移植到Python的所有变体) .
有关详细指南,您可能需要参考my blog article .
首先,你应该决定你的特定目的是什么 . 上面提到了extending and embedding the Python interpreter上的官方Python文档,我可以添加一个好的overview of binary extensions . 用例可分为3类:
accelerator modules :比CPython中运行的等效纯Python代码运行得更快 .
wrapper modules :将现有C接口暴露给Python代码 .
low level system access :访问CPython运行时,操作系统或底层硬件的低级功能 .
为了给其他感兴趣的人提供一些更广泛的视角,因为你的初始问题有点模糊(“到C或C库”),我认为这些信息对你来说可能很有趣 . 在上面的链接中,您可以阅读使用二进制扩展及其替代方案的缺点 .
除了建议的其他答案,如果你想要一个加速器模块,你可以试试Numba . 它工作"by generating optimized machine code using the LLVM compiler infrastructure at import time, runtime, or statically (using the included pycc tool)" .