swig 實踐(python & c/c++)(一)

前言

隨便寫點,不保持更新,構(gòu)想是先簡單說些實踐的東西(這里就是python和c/c++),當(dāng)然也可以支持R,C#,D,Go..這些,后面具體說一下swig這個東西(當(dāng)然如果保持更新的話)。

當(dāng)然我們又不能不先膚淺的談一下swig,最直接的認識就是先上一個圖,
swig.JPG

它可以用來連接(包裝)其它的語言,以便發(fā)揮它們各自的特性。其實大多數(shù)情況下知道這個就已經(jīng)夠了,然后會簡單使用一下就可以,那些大的框架里面用的比較多,譬如時下流行的神經(jīng)網(wǎng)絡(luò)框架Tensorflow,Caffe這些,在溝通后端和前端的語言時,就會大量用到。

開始

然后就從簡單的事例講起,先說安裝,手邊在用windows,就用這個說明就好了,畢竟對于經(jīng)常用Linux的,基本上git,文檔一看就懂的。
win的話從這里下載:http://prdownloads.sourceforge.net/swig/swigwin-3.0.12.zip
然后在環(huán)境變量配置一下,終端swig測試一下就知道可以沒有。同時保持有python和C/C++的環(huán)境。

現(xiàn)在就可以正式開始了,我們假定構(gòu)造一個環(huán)境:有一個簡單c/c++的文件(一般就是寫點效率代碼,算法底層這種的),然后嘗試著用python調(diào)用。
過程是這樣的:

1.搞一個c/c++代碼:

/*File:test.c*/
void quick_sort(int s[], int l, int r)
{
    if (l < r)
    {
        int i = l, j = r, x = s[l];
        while (i < j)
        {
            while (i < j && s[j] >= x)//從右到左找到第一個小于x的數(shù)  
                j--;
            if (i < j)
                s[i++] = s[j];

            while (i < j && s[i] <= x)//從左往右找到第一個大于x的數(shù)  
                i++;
            if (i < j)
                s[j--] = s[i];

        }

        s[i] = x;//i = j的時候,將x填入中間位置  
        quick_sort(s, l, i - 1);//遞歸調(diào)用 
        quick_sort(s, i + 1, r);
    }
}
/*File:test.h*/
void quick_sort(int s[], int l, int r);

隨便寫一個快排的代碼,2.然后構(gòu)造一個swig module。

/* File:test.i*/
%module test

%{
#define SWIG_FILE_WITH_INIT
#include "test.h"
%}

void quick_sort(int s[], int l, int r);

3.終端輸入(當(dāng)前目錄下,否則添加完整路徑)
(C的情況下):

swig -python test.i

(C++的情況下)

swig -c++ -python test.i

會生成兩個文件:test_wrap.c(c)或者test_wrap.cxx(c++)和test.py。當(dāng)然這個.py是不可以直接使用的,還缺點東西。
我們把這里的c/c++文件叫做low-level,生成的py叫做high-level,對于c/c++的生成文件需要進行編譯并鏈接其余的部分(文件中所引用的東西)創(chuàng)建一個擴展module,對于py文件,就是要導(dǎo)入的文件。

說下名字的問題。比如我們用的module:test.i就會默認生成一個加了_wrap的包裝器test_wrap.c。如果要更改的話,可以使用swig的可選項-o指定。生成的py文件就是同名的.py文件。

4.然后我們繼續(xù)后面的話題,如何使用它們。
先說一種方法:使用python的distutils庫,這個東西玩自動化運維的人一定不陌生,當(dāng)然也不準備詳細說明,就是簡單說一下。

from distutils.core import setup, Extension

test_module = Extension('_test',
sources=['test_wrap.c', 'test.c'],
)

setup (name = 'test',
version = '0.1',
author = "孟哲凡",
description = """swig demo""",
ext_modules = [test_module],
py_modules = ["test"],
)

從上面我們可以看到在test_module里的sources是目前已經(jīng)有的,我們需要生成一個_test,然后放到setup函數(shù)里面,當(dāng)然里面還可以放一些其他的東西,可以去看一下。它一般習(xí)慣就叫setup.py。

5.然后就可以了,終端執(zhí)行

python setup.py build_ext --inplace

一般情況下會報錯,說是缺少一個vcvarsall.bat的文件,這個東西是因為python的解釋器底層是用了大量的c語言的,distutils也會用,它找不到,這是個VC里的東西,在python的lib里的_msvccompiler.py里面有說明版本位置這些。一種做法是按照這里的代碼把VC裝成指定版本,版本的計算方法是在終端輸入python會提示 [MSC v.1900 64 bit (AMD64)]這種東西,這個1900就是版本號,前兩個字節(jié) - 6,后兩個字節(jié)/10.0求和就是。所以1900就是13??梢韵螺dvs2013就好了。但是通常情況下我們懶得這么做,因為很多情況下都是裝過vs的,即便只裝vc也麻煩,最簡單的辦法就是把_msvccompiler.py里的位置替換成你已有vs里的vcvarsall.bat目錄位置。詳細的做法百度里會有。簡單說明一下。

當(dāng)上面這個沒有的問題的時候,我們正式開始,執(zhí)行完會生成一個.pyd的文件,.pyd就是一個python引用其它語言的后綴,所以有了這個,之前生成.py文件才有完整的依賴,可以正式使用。

6.大概介紹到這里的時候,這篇文章就應(yīng)該完了。但是細心的人會發(fā)現(xiàn),好像不知道怎么用這個東西,因為我們的例子找的有點隨意,里面有個數(shù)組,這個東西看似司空見慣。但是突然要用python做輸入,有點暈,當(dāng)我們用list或者tuple輸入的時候都會報錯,說是要求一個int []類型的參數(shù),python里面哪有這種東西。但細心一想還是容易懂的,數(shù)組是什么,數(shù)組是指針的簡單形式,也可以說c語言可以沒有數(shù)組(圖個方便),只有指針就夠了。在swig的處理中,把python的函數(shù)和C的指針劃分成一類。

我們剛才談到了函數(shù),所以嘗試在python里面搞個函數(shù),然后扔到里面,發(fā)現(xiàn)現(xiàn)在不會報類型錯誤了,但是會異常退出,因為我們不知道在函數(shù)里面返回點什么,他會認識。所以換個想法,如果我C里面有個函數(shù)可以用python調(diào)用,那C里面放什么我們該知道吧。搞塊內(nèi)存用就可以了,然后順著再搞個賦值函數(shù)就可以了。所以開始去改一下module,加一個內(nèi)聯(lián)塊:

%inline %{

int* array(int l) {
    return (int *)malloc(l * sizeof(int));
}

void array_set(int s[], int i, int v) {
    s[i] = v;
}

void print_array(int s[]) {
    for(int i = 0; i < 6; i++) {
        printf("%d\t",s[i]);
    }
}
%}

當(dāng)然還要加一個free的函數(shù),就不掛在上面了,這樣當(dāng)我們重新的在python里用一下發(fā)現(xiàn)就可以了,得到了正確的輸出。

0   1   3   4   5   12  
Process finished with exit code 0

這部分就完了,后面說另一個辦法:Linux里面用gcc編譯,win下用vs里的功能生成鏈接庫的辦法。然后解釋一下在這個過程中可能出現(xiàn)的一些錯誤。當(dāng)這個都說完以后,就可以正經(jīng)開始這個話題了。這些只是預(yù)熱。因為c++有那么復(fù)雜的語法要用python去調(diào)用,要有很多的細節(jié)和方法。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

友情鏈接更多精彩內(nèi)容