用cython简单包装C代码

用cython简单包装C代码,第1张

用cython简单包装C代码

这是一个从逻辑上将numpy数组传递给外部C函数的小巧但完整的示例

fc( int N, double* a, double* b, double* z )  # z = a + b

使用Cython。(这肯定是众所周知的人。欢迎评论。最后更改:2011年2月23日,对于Cython 0.14。)

首先阅读或略读 Cython构建
并与NumPy一起使用Cython。

2个步骤

  • python f-setup.py build_ext --inplace

    接通
    f.pyx
    fc.cpp
    - >
    f.so
    中,动态库

  • python test-f.py

    import f
    负载
    f.so
    ;
    f.fpy( ... )
    调用C
    fc( ... )

python f-setup.py
应用
distutils
运行用Cython,编译和链接:
cython f.pyx -> f.cpp

编译
f.cpp
fc.cpp

链接
f.o fc.o
- >
f.so
,一个充满活力的lib了Python
import f
将加载。

对于学生,我建议:绘制这些步骤的图表,浏览下面的文件,然后下载并运行它们。

distutils
是一个庞大,复杂的软件包,用于制作要分发的Python软件包并安装它们。在这里,我们仅使用其中的一小部分进行编译并链接到
f.so
。这一步骤与Cython无关,但可能会造成混淆;
.pyx中的简单错误可能会导致g ++编译和链接的页面出现模糊的错误消息。另请参阅
distutils的doc 和/或
distutils上的SO问题。)

make
setup.py
将重新运行
cython f.pyx
g++ -c ... f.cpp
如果
f.pyx
f.cpp

要清理,
rm -r build/

的替代物

setup.py
将是单独运行的步骤,在脚本或生成文件:
cython --cplus f.pyx -> f.cpp # see cython -h

g++ -c ... f.cpp -> f.o

g++ -c ... fc.cpp -> fc.o

cc-lib f.o fc.o -> dynamic library f.so

修改
cc-lib-mac
以下针对您的平台和安装的包装器:它不漂亮,但是很小。

有关Cython包装C的真实示例,请查看几乎所有SciKit中的.pyx文件 。

另请参阅:
适用于NumPy用户的Cython
和SO问题/已标记/ cython。


要解压缩以下文件,将其剪切为一个大文件,例如

cython-numpy-c-demo
,然后在Unix中(在一个干净的新目录中)运行
sh cython-numpy-c-demo

#--------------------------------------------------------------------------------cat >f.pyx <<!# f.pyx: numpy arrays -> extern from "fc.h"# 3 steps:# cython f.pyx  -> f.c# link: python f-setup.py build_ext --inplace  -> f.so, a dynamic library# py test-f.py: import f gets f.so, f.fpy below calls fc()import numpy as npcimport numpy as npcdef extern from "fc.h":     int fc( int N, double* a, double* b, double* z )  # z = a + bdef fpy( N,    np.ndarray[np.double_t,ndim=1] A,    np.ndarray[np.double_t,ndim=1] B,    np.ndarray[np.double_t,ndim=1] Z ):    """ wrap np arrays to fc( a.data ... ) """    assert N <= len(A) == len(B) == len(Z)    fcret = fc( N, <double*> A.data, <double*> B.data, <double*> Z.data )        # fcret = fc( N, A.data, B.data, Z.data )  grr char*    return fcret!#--------------------------------------------------------------------------------cat >fc.h <<!// fc.h: numpy arrays from cython , double*int fc( int N, const double a[], const double b[], double z[] );!#--------------------------------------------------------------------------------cat >fc.cpp <<!// fc.cpp: z = a + b, numpy arrays from cython#include "fc.h"#include <stdio.h>int fc( int N, const double a[], const double b[], double z[] ){    printf( "fc: N=%d a[0]=%f b[0]=%f n", N, a[0], b[0] );    for( int j = 0;  j < N;  j ++ ){        z[j] = a[j] + b[j];    }    return N;}!#--------------------------------------------------------------------------------cat >f-setup.py <<!# python f-setup.py build_ext --inplace#   cython f.pyx -> f.cpp#   g++ -c f.cpp -> f.o#   g++ -c fc.cpp -> fc.o#   link f.o fc.o -> f.so# distutils uses the Makefile distutils.sysconfig.get_makefile_filename()# for compiling and linking: a sea of options.# http://docs.python.org/distutils/introduction.html# http://docs.python.org/distutils/apiref.html  20 pages ...# https://stackoverflow.com/questions/tagged/distutils+pythonimport numpyfrom distutils.core import setupfrom distutils.extension import Extensionfrom Cython.Distutils import build_ext# from Cython.Build import cythonizeext_modules = [Extension(    name="f",    sources=["f.pyx", "fc.cpp"],        # extra_objects=["fc.o"],  # if you compile fc.cpp separately    include_dirs = [numpy.get_include()],  # .../site-packages/numpy/core/include    language="c++",        # libraries=        # extra_compile_args = "...".split(),        # extra_link_args = "...".split()    )]setup(    name = 'f',    cmdclass = {'build_ext': build_ext},    ext_modules = ext_modules,        # ext_modules = cythonize(ext_modules)  ? not in 0.14.1    # version=    # description=    # author=    # author_email=    )# test: import f!#--------------------------------------------------------------------------------cat >test-f.py <<!#!/usr/bin/env python# test-f.pyimport numpy as npimport f  # loads f.so from cc-lib: f.pyx -> f.c + fc.o -> f.soN = 3a = np.arange( N, dtype=np.float64 )b = np.arange( N, dtype=np.float64 )z = np.ones( N, dtype=np.float64 ) * np.NaNfret = f.fpy( N, a, b, z )print "fpy -> fc z:", z!#--------------------------------------------------------------------------------cat >cc-lib-mac <<!#!/bin/shme=${0##*/}case  in"" )    set --  f.cpp fc.cpp ;;  # default: g++ these-h* | --h* )    echo "$me [g++ flags] xx.c yy.cpp zz.o ...    compiles .c .cpp .o files to a dynamic lib xx.so"    exit 1esac# Logically this is simple, compile and link,# but platform-dependent, layers upon layers, gloom, doombase=${1%.c*}base=${base%.o}set -xg++ -dynamic -arch ppc     -bundle -undefined dynamic_lookup     -fno-strict-aliasing -fPIC -fno-common -DNDEBUG `# -g` -fwrapv     -isysroot /Developer/SDKs/MacOSX10.4u.sdk     -I/Library/frameworks/Python.framework/Versions/2.6/include/python2.6     -I${Pysite?}/numpy/core/include     -O2 -Wall     "$@"     -o $base.so# undefs: nm -gpv $base.so | egrep '^ *U _+[^P]'!# 23 Feb 2011 13:38


欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/zaji/5643919.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-12-16
下一篇 2022-12-16

发表评论

登录后才能评论

评论列表(0条)

保存