Python呼叫C 程式的幾種方法

2021-08-21 14:55:08 字數 4836 閱讀 1798

大家都知道python的優點是開發效率高,使用方便,c++則是執行效率高,這兩者可以相輔相成,不管是在python專案中嵌入c++**,或是在c++專案中用python實現外圍功能,都可能遇到python呼叫c++模組的需求,下面列舉出集中c++**匯出成python介面的幾種基本方法,一起來學習學習吧。

python直譯器就是用c實現,因此只要我們的c++的資料結構能讓python認識,理論上就是可以被直接呼叫的。我們實現test1.cpp如下

#include int add(int x, int y)    

int del(int x, int y)

return py_buildvalue("i", add(x, y));

}

return py_buildvalue("i", del(x, y));

} static pymethoddef test_methods =

};

extern "c"

void inittest1()

編譯命令如下

g++ -fpic -shared test1.cpp -i/usr/include/python2.7 -o test1.so
-fpic:生成位置無關目標**,適用於動態連線;

-l path:表示在path目錄中搜尋庫檔案,如-l.表示在當前目錄;

-i path:表示在path目錄中搜尋標頭檔案;

-o file:制定輸出檔案為file;

-shared:生成乙個共享庫檔案;

執行python直譯器,測試如下

>>> import test1 

>>> test1.add(1,2)

3

這裡要注意一下幾點

如果生成的動態庫名字為test1,則原始檔裡必須有inittest1這個函式,且py_initmodule的第乙個引數必須是「test1」,否則python匯入模組會失敗

如果是cpp原始檔,inittest1函式必須用extern "c"修飾,如果是c原始檔,則不需要。原因是python直譯器在導入庫時會尋找init***這樣的函式,而c和c++對函式符號的編碼方式不同,c++在對函式符號進行編碼時會考慮函式長度和引數型別,具體可以通過nm test1.so檢視函式符號,c++filt工具可通過符號反解出函式原型

我們使用和上面同樣的例子,實現test2.cpp如下

#include #include using namespace boost::python; 

int add(const int x, const int y)

int del(const int x, const int y)

boost_python_module(test2)

其中boost_python_module的引數為要匯出的模組名字,編譯命令如下

g++ test2.cpp -fpic -shared -o test2.so -i/usr/include/python2.7 -i/usr/local/include -l/usr/local/lib -lboost_python
注意:編譯時需要指定boost標頭檔案和庫的路徑,我這裡分別是/usr/local/include和/usr/local/lib

或者通過setup.py匯出模組

#!/usr/bin/env python 

from distutils.core import setup

from distutils.extension import extension

setup(name="packagename",

ext_modules=[

extension("test2", ["test2.cpp"],

libraries = ["boost_python"])

])

extension的第乙個引數為模組名,第二個引數為檔名

執行如下命令

python setup.py build
這時會生成build目錄,找到裡面的test2.so,並進入同一級目錄,驗證如下

>>> import test2 

>>> test2.add(1,2)

3>>> test2.del(1,2)

-1

test3.cpp實現如下

#include using namespace boost::python; 

class test

int del(const int x, const int y)

};

boost_python_module(test3)

注意:boost_python_module裡的.def使用方法有點類似python的語法,等同於

class_("test").def("add", &test::add); 

class_("test").def("del", &test::del);

編譯命令如下

g++ test3.cpp -fpic -shared -o test3.so -i/usr/include/python2.7 -i/usr/local/include/boost -l/usr/local/lib -lboost_python
測試如下

>>> import test3 

>>> test = test3.test()

>>> test.add(1,2)

3>>> test.del(1,2)

-1

test4.cpp實現如下

#include using namespace boost::python; 

class test

}; int del(const int x, const int y, const int z = 100)

boost_python_member_function_overloads(add_member_overloads, add, 2, 3)

boost_python_function_overloads(del_overloads, del, 2, 3)

boost_python_module(test4)

這裡add和del函式均採用了預設引數,del為普通函式,add為類成員函式,這裡分別呼叫了不同的巨集,巨集的最後兩個引數分別代表函式的最少引數個數和最多引數個數

編譯命令如下

g++ test4.cpp -fpic -shared -o test4.so -i/usr/include/python2.7 -i/usr/local/include/boost -l/usr/local/lib -lboost_python
測試如下

>>> import test4 

>>> test = test4.test()

>>> print test.add(1,2)

103>>> print test.add(1,2,z=3)

6>>> print test4.del(1,2)

-1>>> print test4.del(1,2,z=3)

-1

既然是匯出為python介面,呼叫者難免會使用python特有的資料結構,比如tuple,list,dict,由於原生態方法太麻煩,這裡只記錄boost的使用方法,假設要實現如下的python函式功能

def square(list_a) 

即對傳入的list每個元素計算平方,返回list型別的結果,**如下

#include boost::python::list square(boost::python::list& data) 

return ret;

}

boost_python_module(test5)

編譯命令如下

g++ test5.cpp -fpic -shared -o test5.so -i/usr/include/python2.7 -i/usr/local/include/boost -l/usr/local/lib -lboost_python
測試如下

>>> import test5 

>>> test5.square([1,2,3])

[1, 4, 9]

boost實現了boost::python::tuple,boost::python::list,boost::python::dict這幾個資料型別,使用方法基本和python保持一致,具體方法可以檢視boost標頭檔案裡的boost/python/tuple.hpp及其它對應檔案

另外比較常用的乙個函式是boost::python::make_tuple(),使用方法如下

boost::python::tuple(int a, int b, int c) 

Python 呼叫shell cmd的幾種方式

1.使用os.system 去呼叫,但是只能返回執行狀態,不能獲取shell cmd執行結果 usr bin python coding utf 8 import os status os.system ps aux grep xcode grep v grep print status2.使用os...

Python呼叫C 程式的幾種方法

大家都知道python的優點是開發效率高,使用方便,c 則是執行效率高,這兩者可以相輔相成,不管是在python專案中嵌入c 或是在c 專案中用python實現外圍功能,都可能遇到python呼叫c 模組的需求,下面列舉出集中c 匯出成python介面的幾種基本方法,一起來學習學習吧。python直...

Python呼叫C程式

目錄 python呼叫c程式的意義 呼叫示例 編寫c程式 編譯c程式 呼叫 我們知道,python具有編寫開發快 程式可讀性良好 支援物件導向的特點。種類繁多的python原生庫和第三方框架使python承擔越來越多的任務。但是python自身的缺陷也確實是python開發者要面對的問題 受制於動態...