真实的国产乱ⅩXXX66竹夫人,五月香六月婷婷激情综合,亚洲日本VA一区二区三区,亚洲精品一区二区三区麻豆

成都創(chuàng)新互聯(lián)網(wǎng)站制作重慶分公司

python的C擴展函數(shù),Python擴展

如何讓python調(diào)用C和C++代碼

如何讓python調(diào)用C和C++代碼

創(chuàng)新互聯(lián)公司服務(wù)緊隨時代發(fā)展步伐,進(jìn)行技術(shù)革新和技術(shù)進(jìn)步,經(jīng)過十年的發(fā)展和積累,已經(jīng)匯集了一批資深網(wǎng)站策劃師、設(shè)計師、專業(yè)的網(wǎng)站實施團隊以及高素質(zhì)售后服務(wù)人員,并且完全形成了一套成熟的業(yè)務(wù)流程,能夠完全依照客戶要求對網(wǎng)站進(jìn)行成都做網(wǎng)站、網(wǎng)站建設(shè)、建設(shè)、維護(hù)、更新和改版,實現(xiàn)客戶網(wǎng)站對外宣傳展示的首要目的,并為客戶企業(yè)品牌互聯(lián)網(wǎng)化提供全面的解決方案。

安裝python后,會有一個chm格式的python手冊。要搞明白如何讓python調(diào)用C/C++代碼(也就是寫python的 extension),你需要征服手冊中的

Extending embedding厚厚的一章。在昨天花了一個小時看地頭暈?zāi)X脹,仍然不知道如何寫python的extension后,查閱了一些其他 書籍,最終在Python Programming On Win32書中找到了教程。

下面記錄一下如何在visual studio 2005中,寫一段C/C++的MessageBox代碼,然后提供后python調(diào)用,最后的結(jié)果當(dāng)然是顯示一個MessageBox.

1. 首先要明白的是,所謂的python擴展(也就是你提供給python的c/c++代碼,不一定是c/c++代碼,可以是其他語言寫的代碼)是一個 dll,并且這個dll放在本機python安裝目錄下的DLLs目錄下(譬如我機器上的路徑是:F:\Program Files\Python25\DLLs),假如我們接下來要寫的擴展module名為mb,python調(diào)用的代碼為: import mb

mb.showMsg("Python's really amazing, I kindda love it!")

python怎么找到我們的mb模塊呢?就是上面說的,我們要生成一個mb.dll,然后拷貝到Dlls目錄下面,為了區(qū)別普通的dll和python專用擴展的dll,我們的 mb.dll修改成mb.pyd(python dll)

2. 搭建環(huán)境,我們要使用python提供的c頭文件和lib庫來進(jìn)行擴展的開發(fā)。 在vs 2005下點擊菜單 "工具"-"選項", 打開選項對話框,選擇"項目和解決方案-VC++目錄", 然后在右邊"顯示以下內(nèi)容的目錄"得comboBox上選擇"包含文件”,添加python的include目錄(我的機器上是"F:\Program

Files\Python25\include"),然后選擇庫文件,添加python的libs目錄(我的機器上是"F:\Program Files\Python25\libs")。

既然擴展是一個dll,接下來我們要建立一個“動態(tài)鏈接庫”工程,然后開始寫代碼:

#include python.h //python.h是包含python一些定義的頭文件,在python的include目錄下 /*

我的python版本是2.5, 因為安裝python后它沒提供debug下的lib庫文件,因此你必須生成release版的dll,

想要生成dll版本的,你要到python官網(wǎng)上自己去下載python源代碼,當(dāng)然你可以繼續(xù)生成release版本的dll,但dll中包含調(diào)試信息

*/

#pragma comment(lib, "python25.lib")

//先不管

static PyObject* mb_showMsg(PyObject* self, PyObject *args); /*

如果你的擴展是mb,那么必須實現(xiàn)一個initmb函數(shù),并且從dll中導(dǎo)出這個函數(shù),但我們在python中調(diào)用import mb時,python會去dll里去調(diào)用

initmb函數(shù),這個函數(shù)告訴python我們有些什么函數(shù),該怎么告訴python我們有一個showMsg函數(shù)呢?下面詳解 */

//必須extern "C"下,這樣不會在C++編譯器里不會更改掉導(dǎo)出的函數(shù)名字,我第一次就犯了這樣的錯誤

extern "C" __declspec(dllexport) void initmb() { /*

當(dāng)調(diào)用mb.showMsg("Python's really amazing, I kindda love it!")時, 相當(dāng)于你告訴python我有一個showMsg函數(shù),我們怎么告訴python去調(diào)用我們dll里的mb_showMsg函數(shù)呢?技巧就是下面的方式, 定義一個字典數(shù)據(jù)結(jié)構(gòu),key = showMsg, value =mb_showMsg,METH_VARARGS是函數(shù)調(diào)用方式,仔細(xì)查手冊吧 */

static PyMethodDef mbMethods[] = { {"showMsg", mb_showMsg, METH_VARARGS},

{NULL, NULL, NULL} /*sentinel,哨兵,用來標(biāo)識結(jié)束*/ };

//告訴python我們的模塊名叫mb, 模塊包含的函數(shù)都在mbMethods字典里 PyObject *m = Py_InitModule("mb", mbMethods); } /*

接下來實現(xiàn)核心功能showMsg */

//第一個self參數(shù)我們用不著,具體查手冊,第二個參數(shù)是python傳給我們的參數(shù),它是一個python的參數(shù)tuple

static PyObject* mb_showMsg(PyObject* self, PyObject *args) {

//我們的showMsg函數(shù)需要的是一個字符串參數(shù) const char* msg = NULL; /*

調(diào)用特殊參數(shù)解碼python傳遞給我們的參數(shù),s是string,我們傳遞接收參數(shù)的變量地址,

如果你的功能函數(shù)需要兩個參數(shù),在PyArg_parseTuple后面繼續(xù)添加接受參數(shù)的變量地址,

這個函數(shù)的原型是類似printf的不定參數(shù)的形式

PyAPI_FUNC(int) PyArg_ParseTuple(PyObject *, const char *, ...); */

if (!PyArg_ParseTuple(args, "s", msg)) return NULL;

//調(diào)用MB

int r = ::MessageBox(NULL, "hello", "Caption:Form C module", MB_ICONINFORMATION | MB_OK);

//返回值

return Py_BuildValue("i", r); }

將上面這段混雜著大量注釋的代碼拷貝到你的編輯器里,然后編譯生成mb.dll,修改后綴成mb.pyd,然后拷貝到python的DLLs目錄下,打開idle(python的交互程序),寫入代碼: import mb

mb.showMsg("Python's really amazing, I kindda love it!")

可以看到彈出來一個MessageBox。

python調(diào)用c函數(shù)

Python是解釋性語言, 底層就是用c實現(xiàn)的, 所以用python調(diào)用C是很容易的, 下面就總結(jié)一下各種調(diào)用的方法, 給出例子, 所有例子都在ubuntu9.10, python2.6下試過

1. Python 調(diào)用 C (base)

想在python中調(diào)用c函數(shù), 如這兒的fact

#include Python.h

int fact(int n)

{

if (n = 1)

return 1;

else

return n * fact(n - 1);

}

PyObject* wrap_fact(PyObject* self, PyObject* args)

{

int n, result;

if (! PyArg_ParseTuple(args, "i:fact", n))

return NULL;

result = fact(n);

return Py_BuildValue("i", result);

}

static PyMethodDef exampleMethods[] =

{

{"fact", wrap_fact, METH_VARARGS, "Caculate N!"},

{NULL, NULL}

};

void initexample()

{

PyObject* m;

m = Py_InitModule("example", exampleMethods);

}

把這段代碼存為wrapper.c, 編成so庫,

gcc -fPIC wrapper.c -o example.so -shared -I/usr/include/python2.6 -I/usr/lib/python2.6/config

然后在有此so庫的目錄, 進(jìn)入python, 可以如下使用

import example

example.fact(4)

2. Python 調(diào)用 C++ (base)

在python中調(diào)用C++類成員函數(shù), 如下調(diào)用TestFact類中的fact函數(shù),

#include Python.h

class TestFact{

public:

TestFact(){};

~TestFact(){};

int fact(int n);

};

int TestFact::fact(int n)

{

if (n = 1)

return 1;

else

return n * (n - 1);

}

int fact(int n)

{

TestFact t;

return t.fact(n);

}

PyObject* wrap_fact(PyObject* self, PyObject* args)

{

int n, result;

if (! PyArg_ParseTuple(args, "i:fact", n))

return NULL;

result = fact(n);

return Py_BuildValue("i", result);

}

static PyMethodDef exampleMethods[] =

{

{"fact", wrap_fact, METH_VARARGS, "Caculate N!"},

{NULL, NULL}

};

extern "C" //不加會導(dǎo)致找不到initexample

void initexample()

{

PyObject* m;

m = Py_InitModule("example", exampleMethods);

}

把這段代碼存為wrapper.cpp, 編成so庫,

g++ -fPIC wrapper.cpp -o example.so -shared -I/usr/include/python2.6 -I/usr/lib/python2.6/config

然后在有此so庫的目錄, 進(jìn)入python, 可以如下使用

import example

example.fact(4)

3. Python 調(diào)用 C++ (Boost.Python)

Boost庫是非常強大的庫, 其中的python庫可以用來封裝c++被python調(diào)用, 功能比較強大, 不但可以封裝函數(shù)還能封裝類, 類成員.

首先在ubuntu下安裝boost.python, apt-get install libboost-python-dev

#include boost/python.hpp

char const* greet()

{

return "hello, world";

}

BOOST_PYTHON_MODULE(hello)

{

using namespace boost::python;

def("greet", greet);

}

把代碼存為hello.cpp, 編譯成so庫

g++ hello.cpp -o hello.so -shared -I/usr/include/python2.5 -I/usr/lib/python2.5/config -lboost_python-gcc42-mt-1_34_1

此處python路徑設(shè)為你的python路徑, 并且必須加-lboost_python-gcc42-mt-1_34_1, 這個庫名不一定是這個, 去/user/lib查

然后在有此so庫的目錄, 進(jìn)入python, 可以如下使用

import hello

hello.greet()

'hello, world'

4. python 調(diào)用 c++ (ctypes)

ctypes is an advanced ffi (Foreign Function Interface) package for Python 2.3 and higher. In Python 2.5 it is already included.

ctypes allows to call functions in dlls/shared libraries and has extensive facilities to create, access and manipulate simple and complicated C data types in Python - in other words: wrap libraries in pure Python. It is even possible to implement C callback functions in pure Python.

#include Python.h

class TestFact{

public:

TestFact(){};

~TestFact(){};

int fact(int n);

};

int TestFact::fact(int n)

{

if (n = 1)

return 1;

else

return n * (n - 1);

}

extern "C"

int fact(int n)

{

TestFact t;

return t.fact(n);

}

將代碼存為wrapper.cpp不用寫python接口封裝, 直接編譯成so庫,

g++ -fPIC wrapper.cpp -o example.so -shared -I/usr/include/python2.6 -I/usr/lib/python2.6/config

進(jìn)入python, 可以如下使用

import ctypes

pdll = ctypes.CDLL('/home/ubuntu/tmp/example.so')

pdll.fact(4)

12

如何使Python嵌入C++應(yīng)用程序

Python容易擴展和嵌入。Python提供的許多標(biāo)準(zhǔn)模塊支持C或者C++接口。Python和C可以一起工作,它可以嵌入到C或者C++的應(yīng)用程序當(dāng)中,因此可用Python語言為應(yīng)用程序提供腳本接口,由于支持跨語言開發(fā)。

可用Python設(shè)計概念化應(yīng)用程序,并逐步移植到C,使用前不必用C重寫應(yīng)用程序。(Jython使Python可以和Java一起工作,使開發(fā)者可以在Python里面調(diào)Java的包,也可以在Java里面使用Python的對象。還有更妙的,由于Jython的解釋器完全用Java編寫,因此可以在支持Java的任何平臺上部署Python程序,甚至WEB瀏覽器也可以直接運行Python腳本。)

提出問題在某個C++應(yīng)用程序中,我們用一組插件來實現(xiàn)一些具有統(tǒng)一接口的功能,我們使用Python來代替動態(tài)鏈接庫形式的插件,這樣可以方便地根據(jù)需求的變化改寫腳本代碼,而不是必須重新編譯鏈接二進(jìn)制的動態(tài)鏈接庫。Python強大的功能足以勝任,但是有一些操作系統(tǒng)特定的功能需要用C++來實現(xiàn),再由Python調(diào)用。所以,最基礎(chǔ)地,我們需要做到:

1. 把Python嵌入到C++應(yīng)用程序中,在C++程序中調(diào)用Python函數(shù)和獲得變量的值;

2. 用C++為Python編寫擴展模塊(動態(tài)鏈接庫),在Python程序中調(diào)用C++開發(fā)的擴展功能函數(shù)。

c可以調(diào)用python嗎

可以的。

C中內(nèi)嵌Python

新建立一個工程,首先需要將工作目錄設(shè)置到Python-3.1.1PCbuild中,以獲取到動態(tài)庫,至于靜態(tài)庫的包含,Include目錄的指定,那自然也是少不了的。文件中需要包含Python.h文件,這也是必須的。

接口中

Py_Initialize();

Py_Finalize();

其他的根據(jù)需求,再引入相應(yīng)的python builder 即可


本文名稱:python的C擴展函數(shù),Python擴展
網(wǎng)站鏈接:http://weahome.cn/article/hdogoc.html

其他資訊

在線咨詢

微信咨詢

電話咨詢

028-86922220(工作日)

18980820575(7×24)

提交需求

返回頂部