使用C++來寫Python擴展模塊

1.起因

    衆所周知,python在處理一些計算量大的任務時效率很低,不僅僅是執行速率,還有內存佔用上,比如下面一段代碼就可以讓你的電腦卡得不行:

alist = [i for i in xrange(1024*1024*1024)]

所以有的時候還是得藉助C/C++來增強Python的效率。

2.方法

    我所知道的大概有三種常用方法:

1>使用ctypes模塊來調用C寫的共享庫,比如:

#測試ctypes調用linux動態庫的能力
from ctypes import *
lib = CDLL("libc.so.6")
printf = lib.printf
printf("Hello World\n")

#查找動態庫
from ctypes.util import find_library
print find_library('c')
output = CDLL(find_library("c")).printf
output("測試成功!\n")
但是用它來調用C++寫的so就不太合適,因爲編譯時c++函數名修飾會給你的函數取一個特殊的字符串,你不能在你的python代碼裏直接使用此函數名,除非你使用的是修飾後的函數名。(在linux下你可以用nm來查看so中的函數名)

2>用C來寫python的擴展模塊,這個沒怎麼用過,以後使用時再記錄在此。

3>用C++來寫python擴展模塊:

我是使用Boost.Python來寫擴展的,先上工作中的代碼片段:

#include <boost/python.hpp> //包含boost.python頭文件
#include <cstdio>
#include <string>

using namespace boost::python;//引入命令空間

class lshw //定義一個類
{
public:
    lshw();
    virtual ~lshw();

    void scan_device();
    string get_xml();

private:
    hwNode *computer;
};

lshw::lshw()
{
    computer = new hwNode("computer", hw::system);
}

lshw::~lshw()
{
    if (computer)
        delete computer;
}

void lshw::scan_device()
{
    enable("output:numeric");
    disable("output:sanitize");
    scan_system(*computer);
}

string lshw::get_xml()
{
    return computer->asXML();
}

void hello()
{
    std::cout << "Hello World!" <<std::endl;
}

BOOST_PYTHON_MODULE(lshw)
{
    class_<lshw, boost::noncopyable > ("lshw", "This is a lshw project python extend", init<>())//導出類中的方法
            .def("scan_device", &lshw::scan_device)
            .def("get_xml", &lshw::get_xml)
            ;
    def("hello",&hello);//導出方法
}
使用boost.python其實結構很簡單,你只要寫很少的boost.python的代碼,你可以把大部分的精力放在C++功能代碼上,花很少的精力就可以把它擴展成python的模塊。下面是我在Ubuntu11.10上的編譯過程:

首先安裝boost.python:

 sudo apt-get install libboost-python1.46.1

再來編譯生成so共享庫文件:

g++ -shared -fPIC lshw.cc -o lshw.so -lboost_python

使用:

import lshw
hw = lshw.lshw()
lshw.hello()
hw.scan_device()
xml = self.hw.get_xml()

當然,lshw.so和你的py文件要讓在同一目錄下,或者你可以把它放在/usr/lib/python2.7/dist-packages/目錄下,你就可以在系統的任何地方加載它了。這段代碼僅僅是展示一下boost.python的使用方法,並沒有實際的意義,也無法編譯通過,只是一個簡單的模型。

1.總結

     Boost.Python  Boost 的一個組件。而 Boost 是目前很紅火的準 C++ 標準庫,它提供了很多組件使得人們可以用 C++ 語言更方便地實現更多的功能。 Boost.Python 就是 Boost 衆多組件中的一個。但它是個特例,它的目的不是單純地增強 C++ 語言的功能,而是希望利用 C++ 語言來增強 Python 語言的能力。使用 Boost.Python 庫,我可以方便地將 C++ 語言寫的程序庫用於 Python 語言,可以用 Python 更好地完成更多的任務。







發佈了30 篇原創文章 · 獲贊 6 · 訪問量 6萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章