使用 SWIG — 為 Python 打包 C/C++設置 1

| | | | | | | | | | |

毫無疑問, 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 自動執行此操作,而不是鍵入命令並找出編譯文件所需的編譯選項。創建如下圖 —


# 文件:setup.py


from distutils.core import setup, Extension

# 模塊名稱

name = "gfg"


# 模塊版本

版本 = "1.0"


#指定擴展名和源文件
# 編譯所需

ext_modules = Extension (name = `_gfg` , sources = [ " gfg.i" , " gfg.c " ] )


setup (name = 名稱,

版本 = 版本,

ext_modules = [ext_modules])

現在編寫以下命令來編譯和安裝模塊 —

$ python setup.py build_ext --inplace 

這應該看起來像終端上類似這樣的東西 —

可能的替代方案

顯然,SWIG —不是創建包裝器的唯一方法,可以根據其要求考慮以下替代方案 —

在下文章我們將了解如何包裝 C++ (OPP) 代碼

鏈接

本文由 Atul Kumar < /強> 。如果你是 Python.Engineering 並且想投稿,你也可以使用 contribute.python.engineering 寫一篇文章或發表一篇文章貢獻@python.engineering。查看我在 Python.Engineering 主頁上出現的文章並幫助其他極客。

如果您發現任何錯誤或想要分享有關所討論主題的更多信息,請發表評論以上。

Shop

Learn programming in R: courses

$

Best Python online courses for 2022

$

Best laptop for Fortnite

$

Best laptop for Excel

$

Best laptop for Solidworks

$

Best laptop for Roblox

$

Best computer for crypto mining

$

Best laptop for Sims 4

$

Latest questions

NUMPYNUMPY

psycopg2: insert multiple rows with one query

12 answers

NUMPYNUMPY

How to convert Nonetype to int or string?

12 answers

NUMPYNUMPY

How to specify multiple return types using type-hints

12 answers

NUMPYNUMPY

Javascript Error: IPython is not defined in JupyterLab

12 answers


Wiki

Python OpenCV | cv2.putText () method

numpy.arctan2 () in Python

Python | os.path.realpath () method

Python OpenCV | cv2.circle () method

Python OpenCV cv2.cvtColor () method

Python - Move item to the end of the list

time.perf_counter () function in Python

Check if one list is a subset of another in Python

Python os.path.join () method