zoukankan      html  css  js  c++  java
  • 使用c/c++扩展python

    用python脚本写应用比较方便,但有时候由于种种原因需要扩展python(比如给程序提供python接口等)。 之前一直想整理下,今天终于坐下来把这件事情给做了,这里记录下,也方便我以后查阅。

    说明: 测试环境中操作系统为CentOS6.5_x64,python版本为2.6

    直接调用动态库

    1、编写模块动态库文代码

    这里以求最大数为示例

    代码(callTest1.cpp)如下:

    extern "C"
    {
        int Max(int i1,int i2)
        {
            return (i1>i2)?i1:i2;
        }
    }  

    在bash中执行以下命令:

    g++ -fPIC -shared -o libcallTest1.so callTest1.cpp

    生成动态库文件libcallTest1.so

    2、使用python调用动态库

    可以通过ctypes调用动态库文件,具体如下:

    #! /usr/bin/env python
    
    from ctypes import *
    import os
    
    so1 = CDLL(os.getcwd() + '/libcallTest1.so')
    print so1.Max(1,3)

    使用boost库扩展python

    这种方式可以直接生成python模块,使用import操作直接导入即可。 当然使用这种方式,需要安装boost库,具体操作这里就不说了,不懂的朋友自己查下。

    boost官网:http://www.boost.org/

    1、模块代码如下:

    文件名:boostCallTest1.cpp

    文件内容:

    int Max(int i1,int i2)
    {
        return (i1>i2)?i1:i2;
    }
    
    #include <boost/python/module.hpp>
    #include <boost/python/def.hpp>
    using namespace boost::python;
    
    BOOST_PYTHON_MODULE(boostCallTest1)
    {
        def("Max",Max);
    }

    2、编写模块编译脚本

    文件名: setup.py

    文件内容:

    #!/usr/bin/env python
    
    from distutils.core import setup
    from distutils.extension import Extension
    
    setup(name="PackageName",
        ext_modules=[
        Extension("boostCallTest1", ["boostCallTest1.cpp"],
        libraries = ["boost_python"])
    ])

    3、编译模块并测试

    编译模块:

    python setup.py build

    会在build目录产生boostCallTest1.so文件,进入该目录,可如下使用:

    >>> import boostCallTest1
    >>> boostCallTest1.Max(1,3)
    3
    

    使用swig扩展python

    SWIG是个帮助使用C或者C++编写的软件能与其它各种高级编程语言进行嵌入联接的开发工具。

    SWIG能应用于各种不同类型的语言包括常用脚本编译语言例如Perl, PHP, Python, Tcl, Ruby and PHP。

    swig官网: http://www.swig.org/download.html

    可以通过yum直接安装:

    yum install swig
    

    1、编写程序代码

    文件名:swigCall.cpp

    内容如下:

    int Max(int i1,int i2)
    {
        return (i1>i2)?i1:i2;
    }

    2、编写接口文件

    文件名:swigCall.i

    内容如下:

    %module swigCall
    %{
    extern int Max(int i1,int i2);
    %}
    
    extern int Max(int i1,int i2);
    

    3、编写Makefile文件

    内容如下:

    all:
            make swigCall
    
    swigCall:
            swig -python -c++ swigCall.i
            g++ -c swigCall.cpp swigCall_wrap.cxx -I/usr/include/python2.7/ -fPIC
            g++ -shared swigCall.o swigCall_wrap.o -o _swigCall.so
    
    clean:
            rm -f swigCall_wrap.c*
            rm -f *.py*
            rm -f *.so
            rm -f *.o

    注意:swig命令中要使用-c++参数编译c++代码

    使用如下:

    >>> import swigCall
    >>> swigCall.Max(1,5)
    5
    >>>

    使用SIP扩展python

    SIP是从SWIG发展而来,专为Python调用C/C++模块使用的。 注意,这里的SIP和voip中的sip不是同一个东西,这里的sip是扩展python用的,voip中的sip是一个通信协议,不要搞混了。

    注意:

    需要安装python sip库;

    1、编写c++模块

    1.1 编写头文件

    文件名: sipCall.h 文件内容:

    class TestMode
    {
    public:  
        int Max(int i1,int i2);
    }; 

    1.2 编写模块内容

    文件名:sipCall.cpp 文件内容:

    #include "sipCall.h"  
    
    int TestMode::Max(int i1,int i2)
    {
        return (i1>i2)?i1:i2;
    }

    2、编写接口文件

    文件名:sipCall.sip 文件内容:

    %Module TestMode
    
    class TestMode {  
    
    %TypeHeaderCode  
    #include "sipCall.h"  
    %End  
    
    public:  
        int Max(int i1,int i2);
    };  
    

    3、生存静态库

    这里用脚本实现,文件名称:genlib.sh

    文件内容:

    #! /bin/bash
    g++ -c -fPIC sipCall.cpp
    ar -crs libsipCall.a sipCall.o
    

    4、编写configure文件

    该脚本用于生成Makefile,内容如下:

    #! /usr/bin/env python
    
    import os  
    import sipconfig  
    
    build_file = "sipCall.sbf"
    config = sipconfig.Configuration()
    cmd = " ".join([config.sip_bin, "-c", ".", "-b", build_file, "sipCall.sip"])  
    os.system(cmd)  
    
    makefile = sipconfig.SIPModuleMakefile(config, build_file)
    makefile.extra_libs = ["sipCall"]  
    makefile.LIBDIR.append(".")  
    makefile.generate()  

    5、运行genlib.sh脚本生成lib文件;

    6、运行configure.py脚本生成Makefile;

    7、运行make生成模块文件(so文件);

    8、python测试如下:

    >>> import TestMode
    >>> dir(TestMode)
    ['TestMode', '__doc__', '__file__', '__name__', '__package__']
    >>> s = TestMode.TestMode()
    >>> s.Max(1,3)
    3 

    本文github地址:

    https://github.com/mike-zhang/mikeBlogEssays/blob/master/2015/20150808_用c++扩展python.md

    欢迎补充

  • 相关阅读:
    【HDU4676】Sum Of Gcd(莫队+欧拉函数)
    【BZOJ5084】hashit(后缀自动机水过)
    【HHHOJ】ZJOI2019模拟赛(十三)03.10 解题报告
    【BZOJ2127】happiness(网络流)
    【CCPC-Wannafly Winter Camp Day4 (Div1) J】跑跑跑路(爬山算法)
    【CCPC-Wannafly Winter Camp Day4 (Div1) H】命命命运(概率DP)
    2019.03.09 ZJOI2019模拟赛 解题报告
    关闭Android/iPhone浏览器自动识别数字为电话号码
    border-radius 在安卓手机竟然不完美支持
    validate.plugin.js 验证插件
  • 原文地址:https://www.cnblogs.com/MikeZhang/p/cppExtenPython_20150808.html
Copyright © 2011-2022 走看看