含有章节索引的中文 文章模板

::-- hoxide [2005-03-10 09:16:46]

1. Python 和 c/c++混编

1.1. 方式对比

k <[email protected]> 
reply-to        [email protected],
to      [email protected],
date    Sat, Mar 22, 2008 at 1:10 PM
subject [CPyUG:44155] Re: 谁用过swig

我大概看了一下,感觉Pyrex没有swig方便,有可能是我对Pyrex不熟悉造成的 几种扩展方法:

  • (1) SWIG
    • 由David Beazley创建,是一个自动的扩展构造工具。它读入注释的C/C++头文件,为python、tcl、perl等多种脚本语言产生wrap代码。SWIG可以包装大量C++特性到Python的扩展模块中。详情可参考http://www.swig.org。
    • 评价:swig简单,可以支持多种脚本文件,但支持的c++特性不完备。
  • (2) SIP
    • 由Phil Thompson创建,是一个C++模块构造器,专门为C++的类创造wrapper。它曾经被用于创建PyQt和PyKDE扩展模块,因此比较出名。详情可参考http://www.riverbankcomputing.co.uk/sip/。

    • 评价:支持C++特征很齐全,但比较复杂。
  • (3) bgen
    • 该工具被包含在标准Python发布包中的模块构建工具集里,由Jack Jansen维护。它用于产生在Macintosh版本可用的Python扩展模块。
  • (4) pyfort
    • 由Paul dubois创建,用来产生Fortran语言生成的扩展模块。详见http://pyfortran.sourceforge.net。
  • (5) cxx
    • 也由Paul Dubois创建,是一个库,为Python的C++扩展提供了友好的API。Cxx允许将许多python对象(如list和tuple)使用到STL的运算中。库也提供了C++异常处理到python异常处理的转化。详见http://cxx.sourceforge.net。
  • (6) WrapPy

    • 由Greg Couch创建,通过读入C++头文件来产生扩展模块。
    • 详见http://www.cgl.ucsf.edu/home/gregc/wrappy/index.html。
  • (7) Boost Python Library
    • 由David Abrahams创建。该库提供了更多与众不同的C++ wrap到python扩展中,而只需要对要扩展的C++类写很少的附加信息。
    • 详见http://www.boost.org/libs/python/doc。
    • 评价:Boost为C++提供了许多实用的库,如Regex(正则表达式库)、Graph(图组件和算法)、concept check(检查泛型编程中的concept)、Thread(可移植的C++多线程库)、Python(把C++类和函数映射到Python之中)、Pool(内存池管理)等等。
    • Boost总体来说是实用价值很高,质量很高的库。并且强调对跨平台的支持。但是Boost中也有很多是实验性质的东西,在实际的开发中实用需要谨慎。
    • boost.python支持的c++特性较多,但是比较复杂。

1.2. c扩展代码在windows中的编译

1.2.1. 使用minGW

  • 由于Windows和*nix不同, 不是一个完整的开发环境, 所以要在windows上为python编写c扩展非常麻烦, 如何编译一直是个问题, 以前以为python2.3一定要MSVC6.0才能编译扩展, 因为我没有MSVC, 所以从来没在windows下搞定编译问题. 现在找到一种用minGW编译的方法. 描述如下 例子简化自python manual

   1 
   2 # spam.c
   3 
   4 #include <Python.h>
   5 
   6 static PyObject *
   7 spam_a(PyObject *self, PyObject *args)
   8 {
   9     return Py_BuildValue("i", 1);
  10 }
  11 
  12 static PyMethodDef SpamMethods[] = {
  13     {"a",  spam_a, METH_VARARGS,
  14      "Just a example"},
  15     {NULL, NULL, 0, NULL}        /* Sentinel */
  16 };
  17 
  18 static PyObject *SpamError;
  19 
  20 
  21 PyMODINIT_FUNC
  22 initspam(void)
  23 {
  24     (void) Py_InitModule("spam", SpamMethods);
  25 }
  26 
  27 int
  28 main(int argc, char *argv[])
  29 {
  30     /* Pass argv[0] to the Python interpreter */
  31     Py_SetProgramName(argv[0]);
  32 
  33     /* Initialize the Python interpreter.  Required. */
  34     Py_Initialize();
  35 
  36     /* Add a static module */
  37     initspam();
  38 
  39 }
  40 

编译命令:

gcc -c -DBUILD_DLL spam.c -If:/python23/include
dllwrap --dllname=spam.dll --driver-name=gcc spam.o f:/python23/libs/python23.lib

ddlwrap会提示说这个不一定是你要的dll

dllwrap: no export definition file provided.
Creating one, but that may not be what you want

不用管它, 可以用

>>> import spam
>>> dir(spam)
['__doc__', '__file__', '__name__', 'a']
>>> spam.a()
1
>>> spam.a.__doc__
'Just a example'


我以前写过一篇blog,你可以看一下 C语言写Python extension实践

  • -- limodou


在win下编译并不麻烦,用vc的编译器就可以,python自带的文档里有说明 例如:

cl /LD spam.c c:\python24\libs\python24.lib

这样就可以得到编译后的DLL了

  • -- Dreamingk

恩, 不错, 收下, 谢谢天成, limodou的blog我也看了, 我试试~~, 计划在这里汇集所有方法~~ --- hoxide