看你用哪種方式
成都創(chuàng)新互聯(lián)專注為客戶提供全方位的互聯(lián)網(wǎng)綜合服務(wù),包含不限于做網(wǎng)站、成都網(wǎng)站制作、鳩江網(wǎng)絡(luò)推廣、成都微信小程序、鳩江網(wǎng)絡(luò)營銷、鳩江企業(yè)策劃、鳩江品牌公關(guān)、搜索引擎seo、人物專訪、企業(yè)宣傳片、企業(yè)代運(yùn)營等,從售前售中售后,我們都將竭誠為您服務(wù),您的肯定,是我們最大的嘉獎(jiǎng);成都創(chuàng)新互聯(lián)為所有大學(xué)生創(chuàng)業(yè)者提供鳩江建站搭建服務(wù),24小時(shí)服務(wù)熱線:13518219792,官方網(wǎng)址:www.cdcxhl.com
如果是import 包名,就是包名.函數(shù)名方式調(diào)用
如果是from 包名 import 函數(shù)名、from 包名 import *,就是直接函數(shù)名就可以調(diào)用
Python是解釋性語言, 底層就是用c實(shí)現(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" //不加會(huì)導(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庫是非常強(qiáng)大的庫, 其中的python庫可以用來封裝c++被python調(diào)用, 功能比較強(qiáng)大, 不但可以封裝函數(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, 這個(gè)庫名不一定是這個(gè), 去/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
大部分函數(shù)都長這樣:函數(shù)名(參數(shù))
要調(diào)用函數(shù)就直接使用函數(shù)名加參數(shù)就可以了。
C/C++對(duì)Python的調(diào)用層次可以分為三個(gè)層次, (1) 高層次的調(diào)用, (2)純Python調(diào)用, (3) Python方法的擴(kuò)展(也就使向Python輸出調(diào)用函數(shù)). 這里我主要討論(1)和(2)兩種方法.
1 高層次的調(diào)用
這是最簡單的一種在C/C++中調(diào)用Python的方法. 它直接的調(diào)用Python提供的C調(diào)用接口函數(shù), 這些函數(shù)主要有: PyRun_SimpleString(), PyRun_SimpleStringFlags(), PyRun_SimpleFile(), PyRun_SimpleFileEx()和PyRun_SimpleFileExFlags()幾個(gè). 函數(shù)的具體用法參考Python的文檔.
這里舉個(gè)例子來說明這種層次的用法:
由這個(gè)例子可見, 在C/C++中調(diào)用Python的內(nèi)容非常簡單, 只要構(gòu)造一個(gè)簡單的Python調(diào)用字符串.這里要注意的就是, Python調(diào)用串語句之間要用'/n'來分開, 且語句之間不能有空格, 如上面的Python字符串不能寫成: "import sys/n print sys.path" , 否則要出錯(cuò)的.
// c/c++ 中 Python 調(diào)用必須的頭文件
#include Python.h
//
int main(int argc, char* argv[])
{
// 初始化Python解析環(huán)境
Py_Initialize();
// 構(gòu)造Python執(zhí)行腳本
char szPyScript[128];
sprintf(szPyScript, "import sys/nprint sys.path");
if(PyRun_SimpleString(szPyScript) != 0)
{
sprintf(stderr, "execute /'%s/'failed!", szPyScript);
return -1;
}
// 清除Python解析環(huán)境
Py_Finalize();
}
//
//
以上的例子也表明了在C/C++中調(diào)用Python的基本結(jié)構(gòu), 就是
(1) 先初始化Python環(huán)境然: Py_Initialize()
(2) 具體對(duì)Python的操作
(3) 清除Python環(huán)境
更復(fù)雜的一個(gè)使用高層調(diào)用的例子, 這個(gè)例子用PyRun_SimpleFile的例子.
這里值得注意是, 在Window中:
(1) 鏈接debug版本的時(shí)候會(huì)自動(dòng)鏈接PythonXX(_d).lib庫, PythonXX_d安裝時(shí)是沒有安裝的, 所以要顯示的指定鏈接PythonXX.lib庫, 不知道VC6.0為什么還會(huì)去找PythonXX_d.lib, 在vs7.0不會(huì).
(2) 編譯時(shí)要以 /MD(多線程DLL) 選項(xiàng)編譯(不論時(shí)debug版本還時(shí)release版本都一樣).
以上我在VC7.0中可以正確的運(yùn)行, 在VC6.0這樣還不行, 可能和我使用的版本有關(guān)系(我用的版本是:Python24.lib). 有知道的請(qǐng)賜教!!
// c/c++ 中 Python 調(diào)用必須的頭文件
#include Python.h
//
int main(int argc, char* argv[])
{
// 初始化Python解析環(huán)境
Py_Initialize();
//
char szFile[] = "PyFile.py";
//sprintf(szPathFile, "%s//%s", szPath, szFile);
FILE* fp = fopen(szFile, "r");
if(PyRun_SimpleFile(fp, szFile) != 0)
{
fclose(fp);
sprintf(stderr, "PyRun_SimpleFile(%s) failed!", saFile);
return -1;
}
fclose(fp);
// 清除Python解析環(huán)境
Py_Finalize();
}
2 純Python調(diào)用
1、在同一個(gè)文件夾下調(diào)用函數(shù):A.py文件:B.py文件:
2、或調(diào)用類:A.py文件:B.py文件:
3、或在不同文件夾下A.py文件的文件路徑:E:\PythonProject\winycgB.py文件:
注意代碼格式
python以縮進(jìn)為標(biāo)準(zhǔn) 而不是像Java 以分號(hào)分隔
函數(shù)調(diào)用需要 寫在main函數(shù)內(nèi)
仔細(xì)檢查你的代碼格式和語法
希望可以幫助你? 請(qǐng)采納? 謝謝