毫無疑問, Numpy, 如此快速高效地執行大量 任務 ?事實上,像 Numpy 這樣的庫並不是完全用 Python 編寫的,庫的某些部分是用 C 編寫的,這提供了更好的性能。編寫完 C 代碼後,我們將它們包裝在 Python 代碼中,作為這些 C 代碼的接口。然後,我們可以使用 Python 語法調用 C 函數,其中實際處理在 C 後台完成,結果作為 Python 對象返回。在本文中,我們將了解如何使用 SWIG 軟件在 Linux 系統上為我們的 C 程序創建 Python 包裝器。
什麼是 SWIG
簡而言之,SWIG —它是一個接受 C / C++ 聲明並將其包裝起來以訪問其他語言的聲明的編譯器,例如 Python、Tcl、Ruby 等。
通常這不需要對現有代碼進行任何更改並創建一個接口在一分鐘內。
創建包裝器的原因
在很多情況下我們需要包裝器,以下是 —
- 為現有的C程序構建解釋接口。
- 為腳本語言構建高性能 C 模塊 ‚Äã‚Äã
- 測試大型 C 程序非常困難,因此我們用一些腳本語言編寫包裝器 ‚Äã‚Äã 像 Python編寫測試非常容易。等
安裝 SWIG
要直接從 apt 存儲庫下載 SWIG,請輸入以下命令 —
sudo apt-get update sudo apt-get install swig
使用 SWIG 編寫 Wrapper
讓我們看看這段代碼在 C 有兩個函數和一個全局變量 —
/ * file: gfg.c * / 代碼>
#include & lt;標準輸入輸出.h >
#include
數學.h >
// 我們的頭文件
# include "gfg.h"
#define ll long long
double
myvar = 3.4;
//計算階乘
ll
int
事實(ll
int
n)
{
if
(n "= 1)
return
1;
else
返回
(n * fact (n-1));
}
// 找到模組
int
my_mod (
int
n,
int
m)
{
return
(n% m);
}
這是我們的頭文件 — ;
long
long
int
fact (
long
long
int
n);
int
my_mod (
int
n,
int
m);
首先我們要創建SWIG接口文件。該文件包含 ANSI C 函數和變量聲明的原型。這裡 —
- % module 指令指定了我們將在 Python 中使用的模塊的名稱。
- %{. . % } 提供了在生成的包裝代碼中插入附加代碼(例如 C 頭文件或附加 C 聲明)的位置。
- % include 指令允許我們包含附加文件,例如頭文件。
/ * file: gfg.i * /
/ * 使用的模塊名稱 * /
% module gfg
% {
/ * 此文件中的所有內容都複製到
包裝文件。包含需要的C頭文件
編譯接口*/
# include "gfg.h"
/* 變量聲明 * /
double
myvar;
%}
/ * 顯式列出函數和變量用於交互 * /
double
myvar;
long
long
int
事實上 (
long
long
int
n1);
int
my_mod (
int
m,
int
n);
/ * 或者如果我們想鏈接所有函數,那麼我們可以直接
包含這樣的頭文件 -
% include & quot; gfg.h & quot;
* /
現在我們將創建包裝代碼使用像
$ swig -python gfg.i
這樣的命令該命令生成名為 "gfg_wrap.c" 的包裝器代碼。這些文件包含我們的 C 源代碼的臃腫版本,具有不同的錯誤處理代碼等。生成 另一個文件 "gfg.py", 這是我們要導入到我們的模塊python 腳本。
之後,我們必須通過編譯 "gfg_wrap.c" 和 "gfg 生成與位置無關的代碼,以便在共享庫中使用.c" 用以下命令:
$ gcc -c -fpic gfg_wrap.c gfg.c -I / use / include / python2.7
替換python2 .7 與您的 Python 版本。這將創建兩個目標文件
"Gfg_wrap.o," 和 "gfg.o," 。在上述命令中 —
- 如果目標機器支持,則生成適合在共享庫中使用的位置無關代碼 (PIC)。此代碼通過全局偏移表(GOT)訪問所有永久地址
注意:如果收到如下錯誤信息可能的原因—
- 你可能沒有 ' Python.h '或
- 您為 ' 輸入了錯誤的位置Python.h '為編譯器
獲取 ' Python.h '您必須使用以下命令 — 安裝 Python-dev,
$ sudo apt-get install python-dev
要找到Python.h的正確路徑,運行以下命令—
$ python -config --cflags
這將輸出類似 —

現在將編譯命令中的路徑替換為 python2.7 的路徑或將版本更改為 python3.5 以獲取 Python 3.5 .
現在,最後,我們必須將生成的對象文件鏈接在一起以創建一個共享對象,這類似於 Windows 上的 DLL 文件。使用以下命令,這將生成一個共享對象文件 "_gfg.so" —
$ gcc -shared gfg.o gfg_wrap.o -o _gfg.so
我們現在可以通過導入來測試 Python shell。確保你在這個 shell 文件所在的目錄中。
> > >導入 gfg > > > res = 事實 (5) > > >水庫 120 > > > res = my_mod (5,2) > > >資源 1 > > > gfg.cvar.myvar 3.4
這裡的 C 變量可以作為。
使用 distutils 編譯和鏈接
我們可以使用 distutils 自動執行此操作,而不是鍵入命令並找出編譯文件所需的編譯選項。創建如下圖 —
現在編寫以下命令來編譯和安裝模塊 — $ python setup.py build_ext --inplace 這應該看起來像終端上類似這樣的東西 — ![]() 可能的替代方案 顯然,SWIG —不是創建包裝器的唯一方法,可以根據其要求考慮以下替代方案 — 在下文章我們將了解如何包裝 C++ (OPP) 代碼 鏈接 本文由 Atul Kumar < /強> 。如果你是 Python.Engineering 並且想投稿,你也可以使用 contribute.python.engineering 寫一篇文章或發表一篇文章貢獻@python.engineering。查看我在 Python.Engineering 主頁上出現的文章並幫助其他極客。 如果您發現任何錯誤或想要分享有關所討論主題的更多信息,請發表評論以上。 ShopLatest questions Wiki |