導航:首頁 > 編程語言 > python監聽c方法返回

python監聽c方法返回

發布時間:2023-05-08 07:22:53

⑴ 如何用python獲得C函數中的變數的值

網頁鏈接

python ctypes 第一句話:

ctypesis a foreign function library for Python. It provides C compatible data types, and allows calling functions in DLLs or shared libraries. It can be used to wrap these libraries in pure Python.

沒看到有說可以直接訪問data。

你可以這樣加這樣的函數:

intget_a()
{
returna;
}

再在python裡面調用。

⑵ python 怎麼調用c語言介面

ctypes: 可直接調用c語言動態鏈接庫。

使用步驟:

1> 編譯好自己的動態連接庫
2> 利用ctypes載入動態連接庫
3> 用ctype調用C函數介面時,需要將python變數類型做轉換後才能作為函數參數,轉換原則見下圖:

#Step1:test.c#include<stdio.h>

intadd(inta,intb)
{
returna+b;
}#Step2:編譯動態鏈接庫(如何編譯動態鏈接庫在本文不詳解,網上資料一大堆。)gcc-fPIC-sharedtest.c-olibtest.so
#Step3:test.py
fromctypesimport*mylib=CDLL("libtest.so")或者cdll.LoadLibrary("libtest.so")add=mylib.add
add.argtypes=[c_int,c_int]#參數類型,兩個int(c_int是ctypes類型,見上表)
add.restype=c_int#返回值類型,int(c_int是ctypes類型,見上表)
sum=add(3,6)

⑶ 如何讓python調用C和C++代碼

要搞明白如何讓python調用C/C++代碼(也就是寫python的extension),你需要征服手冊中的<<Extending && embedding>>厚厚的一章。在昨天花了一個小時看地頭暈腦脹,仍然不知道如何寫python的extension後,查閱了一些其他書籍,最終在<<Python Programming On Win32>>書中找到了教程。
1. 首先要明白的是,所謂的python擴展(也就是你提供給python的c/c++代碼,不一定是c/c++代碼,可以是其他語言寫的代碼)是一個dll,並且這個dll放在本機python安裝目錄下的DLLs目錄下(譬如我機器上的路徑是:F:/Program Files/Python25/DLLs),假如我們接下來要寫的擴展mole名為mb,python調用的代碼為:import mbmb.showMsg("Python's really amazing, I kindda love it!")
2. 搭建環境,我們要使用python提供的c頭文件和lib庫來進行擴展的開發。
在vs 2005下點擊菜單 "工具"->"選項", 打開選項對話框,選擇"項目和解決方案->VC++目錄", 然後在右邊"顯示以下內容的目錄"得comboBox上選擇"包含文件」,添加python的include目錄(我的機器上是"F:/Program Files/Python25/include"),然後選擇庫文件,添加python的libs目錄(我的機器上是"F:/Program Files/Python25/libs")。
既然擴展是一個dll,接下來我們要建立一個「動態鏈接庫」工程,然後開始寫代碼:
#include <python.h> //python.h是包含python一些定義的頭文件,在python的include目錄下/*我的python版本是2.5, 因為安裝python後它沒提供debug下的lib庫文件,因此你必須生成release版的dll,
想要生成dll版本的,你要到python官網上自己去下載python源代碼,當然你可以繼續生成release版本的dll,但dll中包含調試信息*/#pragma comment(lib, "python25.lib")//先不管static PyObject* mb_showMsg(PyObject* self, PyObject *args);/*如果你的擴展是mb,那麼必須實現一個initmb函數,並且從dll中導出這個函數,但我們在python中調用import mb時,python會去dll里去調用
extern "C" __declspec(dllexport) void initmb(){/*當調用mb.showMsg("Python's really amazing, I kindda love it!")時, 相當於你告訴python我有一個showMsg函數,我們怎麼告訴python去調用我們dll里的mb_showMsg函數呢?技巧就是下面的方式,定義一個字典數據結構,key => showMsg, value =>mb_showMsg,METH_VARARGS是函數調用方式,仔細查手冊吧*/static PyMethodDef mbMethods[] = {
{"showMsg", mb_showMsg, METH_VARARGS},
{NULL, NULL, NULL} /*sentinel,哨兵,用來標識結束*/};//告訴python我們的模塊名叫mb, 模塊包含的函數都在mbMethods字典里
PyObject *m = Py_InitMole("mb", mbMethods);}/*接下來實現核心功能showMsg*///第一個self參數我們用不著,具體查手冊,第二個參數是python傳給我們的參數,它是一個python的參數tuple
static PyObject* mb_showMsg(PyObject* self, PyObject *args){//我們的showMsg函數需要的是一個字元串參數
const char* msg = NULL;/*調用特殊參數解碼python傳遞給我們的參數,s是string,我們傳遞接收參數的變數地址,
如果你的功能函數需要兩個參數,在PyArg_parseTuple後面繼續添加接受參數的變數地址,
這個函數的原型是類似printf的不定參數的形式
PyAPI_FUNC(int) PyArg_ParseTuple(PyObject *, const char *, ...);*/if (!PyArg_ParseTuple(args, "s", &msg))
return NULL;//調用MBint r = ::MessageBox(NULL, "hello", "Caption:Form C mole", MB_ICONINFORMATION | MB_OK);//返回值return Py_BuildValue("i", r);}將上面這段混雜著大量注釋的代碼拷貝到你的編輯器里,然後編譯生成mb.dll,修改後綴成mb.pyd,然後拷貝到python的DLLs目錄下,打開idle(python的交互程序),寫入代碼:import mbmb.showMsg("Python's really amazing, I kindda love it!")

⑷ python 調用C可執行程序

比如參數是ARG1,ARG2,輸入字元串是TEST

import subprocess as sub
p = sub.Popen(['alignment ARG1 ARG2'], shell = True, stdin = sub.PIPE, stdout = sub.PIPE, stderr = sub.PIPE)
(out,err) = p.communicate(input = 'TEST')

out是執行後的標准輸出

「問題補充:那個C可執行程序需要CTRL + C 才能退出,就不知道該怎麼辦了」

可以發送SIGINT信號給可執行程序
Popen.send_signal(signal)

等同於ctrl + c

⑸ 如何實現 C/C++ 與 Python 的通信

屬於混合編程的問題。較全面的介紹一下,不僅限於題主提出的問題。
以下討論中,Python指它的標准實現,即CPython(雖然不是很嚴格)

本文分4個部分

C/C++ 調用 Python (基礎篇)— 僅討論Python官方提供的實現方式
Python 調用 C/C++ (基礎篇)— 僅討論Python官方提供的實現方式
C/C++ 調用 Python (高級篇)— 使用 Cython
Python 調用 C/C++ (高級篇)— 使用 SWIG

練習本文中的例子,需要搭建Python擴展開發環境。具體細節見搭建Python擴展開發環境 - 蛇之魅惑 - 知乎專欄

1 C/C++ 調用 Python(基礎篇)
Python 本身就是一個C庫。你所看到的可執行體python只不過是個stub。真正的python實體在動態鏈接庫里實現,在Windows平台上,這個文件位於 %SystemRoot%\System32\python27.dll。

你也可以在自己的程序中調用Python,看起來非常容易:

//my_python.c
#include <Python.h>

int main(int argc, char *argv[])
{
Py_SetProgramName(argv[0]);
Py_Initialize();
PyRun_SimpleString("print 'Hello Python!'\n");
Py_Finalize();
return 0;
}

在Windows平台下,打開Visual Studio命令提示符,編譯命令為
cl my_python.c -IC:\Python27\include C:\Python27\libs\python27.lib

在Linux下編譯命令為
gcc my_python.c -o my_python -I/usr/include/python2.7/ -lpython2.7

在Mac OS X 下的編譯命令同上

產生可執行文件後,直接運行,結果為輸出
Hello Python!

Python庫函數PyRun_SimpleString可以執行字元串形式的Python代碼。

雖然非常簡單,但這段代碼除了能用C語言動態生成一些Python代碼之外,並沒有什麼用處。我們需要的是C語言的數據結構能夠和Python交互。

下面舉個例子,比如說,有一天我們用Python寫了一個功能特別強大的函數:

def great_function(a):
return a + 1

接下來要把它包裝成C語言的函數。我們期待的C語言的對應函數應該是這樣的:

int great_function_from_python(int a) {
int res;
// some magic
return res;
}

首先,復用Python模塊得做『import』,這里也不例外。所以我們把great_function放到一個mole里,比如說,這個mole名字叫 great_mole.py

接下來就要用C來調用Python了,完整的代碼如下:
#include <Python.h>

int great_function_from_python(int a) {
int res;
PyObject *pMole,*pFunc;
PyObject *pArgs, *pValue;

/* import */
pMole = PyImport_Import(PyString_FromString("great_mole"));

/* great_mole.great_function */
pFunc = PyObject_GetAttrString(pMole, "great_function");

/* build args */
pArgs = PyTuple_New(1);
PyTuple_SetItem(pArgs,0, PyInt_FromLong(a));

/* call */
pValue = PyObject_CallObject(pFunc, pArgs);

res = PyInt_AsLong(pValue);
return res;
}

從上述代碼可以窺見Python內部運行的方式:

所有Python元素,mole、function、tuple、string等等,實際上都是PyObject。C語言里操縱它們,一律使用PyObject *。
Python的類型與C語言類型可以相互轉換。Python類型XXX轉換為C語言類型YYY要使用PyXXX_AsYYY函數;C類型YYY轉換為Python類型XXX要使用PyXXX_FromYYY函數。
也可以創建Python類型的變數,使用PyXXX_New可以創建類型為XXX的變數。
若a是Tuple,則a[i] = b對應於 PyTuple_SetItem(a,i,b),有理由相信還有一個函數PyTuple_GetItem完成取得某一項的值。
不僅Python語言很優雅,Python的庫函數API也非常優雅。

現在我們得到了一個C語言的函數了,可以寫一個main測試它
#include <Python.h>

int great_function_from_python(int a);

int main(int argc, char *argv[]) {
Py_Initialize();
printf("%d",great_function_from_python(2));
Py_Finalize();
}

編譯的方式就用本節開頭使用的方法。
在Linux/Mac OSX運行此示例之前,可能先需要設置環境變數:
bash:
export PYTHONPATH=.:$PYTHONPATH

csh:
setenv PYTHONPATH .:$PYTHONPATH

2 Python 調用 C/C++(基礎篇)
這種做法稱為Python擴展。
比如說,我們有一個功能強大的C函數:
int great_function(int a) {
return a + 1;
}

期望在Python里這樣使用:
>>> from great_mole import great_function
>>> great_function(2)
3

考慮最簡單的情況。我們把功能強大的函數放入C文件 great_mole.c 中。
#include <Python.h>

int great_function(int a) {
return a + 1;
}

static PyObject * _great_function(PyObject *self, PyObject *args)
{
int _a;
int res;

if (!PyArg_ParseTuple(args, "i", &_a))
return NULL;
res = great_function(_a);
return PyLong_FromLong(res);
}

static PyMethodDef GreateMoleMethods[] = {
{
"great_function",
_great_function,
METH_VARARGS,
""
},
{NULL, NULL, 0, NULL}
};

PyMODINIT_FUNC initgreat_mole(void) {
(void) Py_InitMole("great_mole", GreateMoleMethods);
}

除了功能強大的函數great_function外,這個文件中還有以下部分:

包裹函數_great_function。它負責將Python的參數轉化為C的參數(PyArg_ParseTuple),調用實際的great_function,並處理great_function的返回值,最終返回給Python環境。

出表GreateMoleMethods。它負責告訴Python這個模塊里有哪些函數可以被Python調用。導出表的名字可以隨便起,每一項有4
個參數:第一個參數是提供給Python環境的函數名稱,第二個參數是_great_function,即包裹函數。第三個參數的含義是參數變長,第四個
參數是一個說明性的字元串。導出表總是以{NULL, NULL, 0, NULL}結束。
導出函數initgreat_mole。這個的名字不是任取的,是你的mole名稱添加前綴init。導出函數中將模塊名稱與導出表進行連接。

在Windows下面,在Visual Studio命令提示符下編譯這個文件的命令是
cl /LD great_mole.c /o great_mole.pyd -IC:\Python27\include C:\Python27\libs\python27.lib

/LD 即生成動態鏈接庫。編譯成功後在當前目錄可以得到 great_mole.pyd(實際上是dll)。這個pyd可以在Python環境下直接當作mole使用。

在Linux下面,則用gcc編譯:
gcc -fPIC -shared great_mole.c -o great_mole.so -I/usr/include/python2.7/ -lpython2.7

在當前目錄下得到great_mole.so,同理可以在Python中直接使用。

本部分參考資料

《Python源碼剖析-深度探索動態語言核心技術》是系統介紹CPython實現以及運行原理的優秀教程。
Python 官方文檔的這一章詳細介紹了C/C++與Python的雙向互動Extending and Embedding the Python Interpreter
關於編譯環境,本文所述方法僅為出示原理所用。規范的方式如下:3. Building C and C++ Extensions with distutils
作為字典使用的官方參考文檔 Python/C API Reference Manual

用以上的方法實現C/C++與Python的混合編程,需要對Python的內部實現有相當的了解。接下來介紹當前較為成熟的技術Cython和SWIG。

3 C/C++ 調用 Python(使用Cython)


前面的小節中談到,Python的數據類型和C的數據類型貌似是有某種「一一對應」的關系的,此外,由於Python(確切的說是CPython)本身是
由C語言實現的,故Python數據類型之間的函數運算也必然與C語言有對應關系。那麼,有沒有可能「自動」的做替換,把Python代碼直接變成C代碼
呢?答案是肯定的,這就是Cython主要解決的問題。

安裝Cython非常簡單。Python 2.7.9以上的版本已經自帶easy_install:
easy_install -U cython

在Windows環境下依然需要Visual
Studio,由於安裝的過程需要編譯Cython的源代碼,故上述命令需要在Visual
Studio命令提示符下完成。一會兒使用Cython的時候,也需要在Visual
Studio命令提示符下進行操作,這一點和第一部分的要求是一樣的。

繼續以例子說明:
#great_mole.pyx
cdef public great_function(a,index):
return a[index]

這其中有非Python關鍵字cdef和public。這些關鍵字屬於Cython。由於我們需要在C語言中使用
「編譯好的Python代碼」,所以得讓great_function從外面變得可見,方法就是以「public」修飾。而cdef類似於Python的
def,只有使用cdef才可以使用Cython的關鍵字public。

這個函數中其他的部分與正常的Python代碼是一樣的。

接下來編譯 great_mole.pyx
cython great_mole.pyx

得到great_mole.h和great_mole.c。打開great_mole.h可以找到這樣一句聲明:
__PYX_EXTERN_C DL_IMPORT(PyObject) *great_function(PyObject *, PyObject *)

寫一個main使用great_function。注意great_function並不規定a是何種類型,它的
功能只是提取a的第index的成員而已,故使用great_function的時候,a可以傳入Python
String,也可以傳入tuple之類的其他可迭代類型。仍然使用之前提到的類型轉換函數PyXXX_FromYYY和PyXXX_AsYYY。

//main.c
#include <Python.h>
#include "great_mole.h"

int main(int argc, char *argv[]) {
PyObject *tuple;
Py_Initialize();
initgreat_mole();
printf("%s\n",PyString_AsString(
great_function(
PyString_FromString("hello"),
PyInt_FromLong(1)
)
));
tuple = Py_BuildValue("(iis)", 1, 2, "three");
printf("%d\n",PyInt_AsLong(
great_function(
tuple,
PyInt_FromLong(1)
)
));
printf("%s\n",PyString_AsString(
great_function(
tuple,
PyInt_FromLong(2)
)
));
Py_Finalize();
}

編譯命令和第一部分相同:
在Windows下編譯命令為
cl main.c great_mole.c -IC:\Python27\include C:\Python27\libs\python27.lib

在Linux下編譯命令為
gcc main.c great_mole.c -o main -I/usr/include/python2.7/ -lpython2.7

這個例子中我們使用了Python的動態類型特性。如果你想指定類型,可以利用Cython的靜態類型關鍵字。例子如下:

#great_mole.pyx
cdef public char great_function(const char * a,int index):
return a[index]

cython編譯後得到的.h里,great_function的聲明是這樣的:
__PYX_EXTERN_C DL_IMPORT(char) great_function(char const *, int);

很開心對不對!
這樣的話,我們的main函數已經幾乎看不到Python的痕跡了:
//main.c
#include <Python.h>
#include "great_mole.h"

int main(int argc, char *argv[]) {
Py_Initialize();
initgreat_mole();
printf("%c",great_function("Hello",2));
Py_Finalize();
}

在這一部分的最後我們給一個看似實用的應用(僅限於Windows):
還是利用剛才的great_mole.pyx,准備一個dllmain.c:
#include <Python.h>
#include <Windows.h>
#include "great_mole.h"

extern __declspec(dllexport) int __stdcall _great_function(const char * a, int b) {
return great_function(a,b);
}

BOOL WINAPI DllMain(HINSTANCE hinstDLL,DWORD fdwReason,LPVOID lpReserved) {
switch( fdwReason ) {
case DLL_PROCESS_ATTACH:
Py_Initialize();
initgreat_mole();
break;
case DLL_PROCESS_DETACH:
Py_Finalize();
break;
}
return TRUE;
}

在Visual Studio命令提示符下編譯:
cl /LD dllmain.c great_mole.c -IC:\Python27\include C:\Python27\libs\python27.lib

會得到一個dllmain.dll。我們在Excel裡面使用它,沒錯,傳說中的Excel與Python混合編程:

參考資料:Cython的官方文檔,質量非常高:
Welcome to Cython』s Documentation

⑹ python怎麼接受c++字元串返回值

方法如下:
from ctypes import *
hello_lib = cdll.LoadLibrary("虧源賀銷派hello.so")
hello = hello_lib.hello
hello.restype = c_char_p
print hello(「裂禪world」)

⑺ 用cmd運行python後怎麼返回cmd

在windows
cmd下運行python,需要設置環境變數,不設環境變數是不能在cmd下運行python的,
現在假設python安裝在C:\Python25目錄下,設置環境變數方法如下:
方法一、我的電腦->屬性->高級->環境變數->系統變數
,在系統變數里找到PATH,雙擊PATH,在結尾加上
";C:\Python25"(不要引號)
方法二、快捷鍵(WIN+R)在「運行」中輸入「cmd
」然後在命令提示符中輸入set
PATH=%PATH%;C:\Python25,接下來,再在當前的
cmd下輸入python,即可運行。

⑻ 請問python中如何傳遞一個字元串給c程序dll中c函數,同時c函數如何返回一個字元串給python

用ctypes,

>>> from ctypes import *
>>> libc=cdll.msvcrt
>>> libc.printf("hello %s\n","world")
hello world
12
>>>

>>> p = create_string_buffer("Hello", 30)
>山拆>> n=libc.sprintf(p,"hello %s\n","world")
>>> n
12
>>> print p
<拍歷ctypes.c_char_Array_30 object at 0x02247C10>
>>> dir(p)
['__class__', '__ctypes_from_outparam__', '__delattr__', '__delitem__', '__delsl
ice__', '__dict__', '__doc__', '__format__', '__getattribute__', '__getitem__',
'__getslice__', '__hash__', '__init__', '__len__', '__mole__', '__new__', '__r
ece__', '__rece_ex__', '__repr__', '__setattr__', '__setitem__', '__setslice
__', '__setstate__', '__sizeof__', '__str__', '__subclasshook__', '襲唯搜__weakref__',
'_b_base_', '_b_needsfree_', '_length_', '_objects', '_type_', 'raw', 'value']
>>> p.value
'hello world\n'
>>>

⑼ python 調用c++程序, c++程序如何返回數組給python

C/C++不能直接返回一個數組。這是由於在C/C++中,數組不是一種類型,因此不能被直接返回。
一般有兩種方法來返回一個數組。
第一種方法:
返回一個指向數組的指針,例如char (*retArray)[10]聲明了一個函數retArray,該函數可以返回指向具有10個char元素的數組
第二種方法:
如果你不喜歡用指針的形式返回數組,那麼可以採用返回一個結構的形式。這種形式相對較安全,可以避免忘記釋放指針而造成內存泄露,也可以避免訪問懸掛指針造成的錯誤。但缺點是由於結構是先拷貝再返回,因此如果結構較大時,會影響效率和佔用較大內存。
這是C的限制,Python調用C也是這種情況

⑽ python 函數返回值返回到哪裡

python 函數返回值有兩種形式: 1 返回一個值。 2 返回多個值。 現看看返回一個值的吧。
def firstvalue(a,b):
c = a + b
return c

print firstvalue(1,2)結果:3
再看看返回多個值的: 那怎麼可以返回多個值呢,其他的語言一般調用函數的話,只能返回一個值,可能我不太熟悉所有的語言,我知道的語言只能返回一個值,而python可以返回多個值,感覺非常方便,發代碼看下:
def secondvalue(a,b):
c = a + b
return (a,b,c)

x,y,z = secondvalue(1,2)
print 'x:',x,'y:',y,'z:',z

可能上面的東西寫的有點簡單,但是有的細節處理也很重要。順便分享下我如何學習python的經歷把,大家沒事拍拍磚。

閱讀全文

與python監聽c方法返回相關的資料

熱點內容
自家wifi怎麼能加密 瀏覽:642
紅米k40加密門禁卡 瀏覽:845
什麼樣的源碼好看 瀏覽:156
手機主伺服器有什麼用 瀏覽:610
程序編寫命令 瀏覽:597
android發送心跳包 瀏覽:385
指標源碼和原理 瀏覽:700
汽車空調壓縮吸盤 瀏覽:208
崽崽因app版本不同不能邀請怎麼辦 瀏覽:686
poa演算法得到的解為全局最優解 瀏覽:926
python符號表達式 瀏覽:34
威馳壓縮機繼電器 瀏覽:871
華為手機怎麼設置移動數據app 瀏覽:959
空調壓縮機哪的廠家多 瀏覽:390
手指速演算法24加7怎麼算 瀏覽:139
如何用python寫vlookup函數 瀏覽:798
社保加密狗廠商 瀏覽:216
php編譯運行說法 瀏覽:957
程序員說喂 瀏覽:258
抖音直播雲伺服器 瀏覽:629