如何在C/C++中包裝Python物件?


要將現有的C或C++功能包裝到Python中,有很多選項可用,它們是:使用PyMethodDef和Py_InitModule進行手動包裝、SWIG、Pyrex、ctypes、SIP、Boost.Python和pybind1。

使用SWIG模組

讓我們以一個C函式為例,然後使用SWIG將其調整為Python。SWIG代表“簡單包裝器介面生成器”,它能夠將C包裝到多種語言中,例如Python、PHP、TCL等。

示例

考慮example.c檔案中簡單的階乘函式fact()。

/* File : example.c */
 
 #include <example.h>
// calculate factorial
 int fact(int n) {
     if (n <= 1) return 1;
     else return n*fact(n-1);
 }

標頭檔案

int fact(int n);                                                        

介面檔案

現在,為了將上述C函式新增到Python語言中,您需要編寫一個“介面檔案”,它是SWIG的輸入。

/* example.i */
%module example 
%{ /* Put header files here or function declarations like below */
extern int fact(int n); 
%} 

extern int fact(int n); 

建立Python包裝器

只需按照以下步驟,我們就可以將C程式碼包裝到Python模組中。

>swig -python example.i

這將建立名為“example_wrap.c”和“example.py”的新檔案。“example_wrap.c”檔案包含我們原始C程式碼的膨脹版本,其中包含各種錯誤處理程式碼等。“example.py”將在我們的Python指令碼中匯入。

之後執行以下命令

>gcc -c example.c example_wrap.c \ -I/usr/local/include/python2.7

這將生成位置無關程式碼,該程式碼將透過編譯“example_wrap.c”和“example.py”檔案在共享庫中使用。注意:將python2.7替換為您的Python版本。這將生成兩個目標檔案“example_wrap.o”和“example.o”。

>ld -shared example.o example_wrap.o -o _example.so

最後,我們必須將生成的object檔案連結在一起以建立一個共享物件,這類似於Windows中的dll檔案。使用上述命令,這將生成一個“_example.so”共享物件檔案。現在我們可以透過匯入它來測試Python包裝器了。

>>> import example 
>>> example.fact(5) 
120

使用Boost庫

現在,讓我們以一個C++函式為例,然後使用Boost.Python將其包裝到Python中。

Boost.Python庫用於在C/C++中包裝Python物件。Boost Python庫是一個用於連線Python和C++的框架。無需使用任何特殊工具,它允許我們快速而無縫地將C++類、函式和物件公開給Python,反之亦然。

它旨在非侵入式地包裝C++介面,因此您無需更改C++程式碼即可進行包裝。該庫使用高階超程式設計技術,簡化了使用者的語法,使包裝程式碼看起來像是一種宣告性介面定義語言(IDL)。

示例

讓我們來看一個基本的包裝器:我們在C++檔案中有一個函式“foo”。

char const* foo()
{
   return "Sample,function";
}

然後編寫一個Boost.python包裝器,以將“foo”函式公開給Python。

#include <boost/python.hpp>

BOOST_PYTHON_MODULE(sample)
{
    using namespace boost::python;
    def("foo",foo);
}

從上述設定中,我們構建了一個共享庫。現在,Python可以訪問生成的DLL。這是一個Python會話示例:

<<< import sample
<<< print(sample.foo())

輸出

Sample, function

透過使用這個基本的foo函式,我們已經成功地將C++函式共享給了Python。

更新於:2023年8月24日

瀏覽量:370

啟動您的職業生涯

透過完成課程獲得認證

開始學習
廣告
© . All rights reserved.