『壹』 求幫忙把python翻譯成c語言
Python的
簡單
的Python的特點是一種語言代表了一種簡單的意識形態。閱讀一個良好的Python程序就感覺像是在讀英語,但英語很嚴格!這種偽代碼的Python的本質是它最大的優勢之一。它可以讓你專注於解決問題,而不是語言本身。
了解
正如你所看到的,Python是非常容易使用。正如前面提到的,Python有一個很簡單的語法。 - 免費,開源
Python是FLOSS(自由/開源軟體)。簡單地說,你可以自由地發布這個軟體的拷貝,閱讀它的源代碼,它,把它的一部分用於新的自由軟體。 FLOSS是一個以社區為基礎的知識共享的概念。這就是為什麼Python是那麼好,原因之一 - 它是一組想看看是誰創造並不斷完善更好的Python。
高級語言
當您使用Python編程語言,你需要考慮如何管理底層細節,如程序使用的一類內存。點擊看詳細可移植性由於它的開源本質,Python已經被移植在許多平台上(經過改動使它能夠在不同的平台上工作)。如果你小心地避免使用依賴於系統的特性,那麼你所有的Python程序無需任何這些平台上運行。
這些平台,包括Linux,Windows,FreeBSD的,Macintosh電腦時,Solaris,OS / 2,Amiga上,AROS,AS / 400,BeOS的,OS / 390和z / OS,Palm操作系統,QNX,VMS,Psion公司,的Acom RISC OS,VxWorks的游戲機,夏普的Zaurus,Windows CE和PocketPC的連!
解釋性
這需要一些解釋。
編譯語言,如C或C ++程序可以寫入到從源文件(即C或C ++)轉換到您的計算機使用的語言(二進制代碼,即0和1)。通過這個過程中,編譯器和各種標志和選項。當你運行你的程序,鏈接器/載入器軟體從硬碟復制你的程序到內存並運行。
的Python,程序不需要編譯成二進制代碼。可以直接從源代碼運行程序。在計算機內部,Python解釋器把源代碼轉換成中間形式稱為位元組碼,然後把它翻譯成機器語言的計算機並運行。事實上,因為你不再需要擔心如何編譯程序,如何保證正確的連接轉載圖書館等,所有這些都使得使用Python更加容易。因為你只需要你的Python程序拷貝到另一台計算機,它可以工作,這也使得你的Python程序更加便攜。點擊看詳細的Python支持面向對象的面向過程的編程也支持面向對象的編程。在這個過程中,面向對象語言中,程序是建立了由過程或僅僅是可重復使用的代碼的功能。在面向對象的語言中,程序是由累積數據和功能的對象的組合。和Java相比其他主要的語言如C ++,Python有實現面向對象編程一個非常強大和簡單的方法。
可擴展性
如果您需要一段關鍵代碼運行得更快或者希望某些演算法不公開,你可以把你寫在C或C計劃的一部分++,然後在你的Python程序來使用它們。
嵌入
可以嵌入的Python你的C / C ++程序中,讓你的程序提供腳本功能。
豐富的庫
Python標准庫確實很龐大。它可以幫助你處理各種工作,包括正則表達式,文檔生成,單元測試,線程,資料庫,Web瀏覽器,CGI,FTP,電子郵件,XML,XML-RPC,HTML,WAV文件,密碼,GUI(圖形用戶界面),Tk和其他系統相關的操作。請記住,只要是Python的安裝,所有這些功能都可用。這被稱為Python的「功能齊全」的概念。
除了標准庫,還有許多其他高質量的庫,如wxPython的,扭曲和Python圖像庫等等。
『貳』 【python-C相互調用】python里的dict如何作為參數傳入.so中的c語言函數
#include<stdio.h>
#include<stdlib.h>
#include<Python.h>
staticPyObject*
wmf_reverse(PyObject*self,PyObject*args,PyObject*kwargs){
staticchar*kwlist[]={"name",NULL};
char*name=NULL;
PyObject*retval=NULL;
//問題1:只取一個字元串,format應該是"s"
//>>>if(PyArg_ParseTupleAndKeywords(args,keyds,"isi",kwlist,&name))
if(PyArg_ParseTupleAndKeywords(args,kwargs,"s",kwlist,&name)){
retval=(PyObject*)Py_BuildValue("i",1);
printf("%s ",name);
//問題2:不要釋放
//>>>free(name);
}else{
retval=(PyObject*)Py_BuildValue("i",0);
}
returnretval;
}
staticPyMethodDef
wmf_methods[]={
{"reverse",(PyCFunction)wmf_reverse,METH_VARARGS|METH_KEYWORDS,"reverse"},
//問題3:方法定義表,應該用一條空記錄來表示結束。
{NULL,NULL,0,NULL},
};
//問題4:沒有定義mole
staticstructPyMoleDef
wmf_mole={
PyMoleDef_HEAD_INIT,
"wmf",/*nameofmole*/
NULL,/*moledocumentation,maybeNULL*/
-1,/*sizeofper-interpreterstateofthemole,
or-.*/
wmf_methods,
};
//問題5:入口函數要聲明為:PyMODINIT_FUNC
PyMODINIT_FUNC
PyInit_wmf(void){
//問題6:Py_InitMole要初始化的是模塊,不是方法。所以傳方法定義是錯誤的。
//另外,python2.x是用Py_Init_mole,python3.x改用PyMole_Create了。
//兩者略有差別,自己注意一下吧。這里我用的是python3.x。
//Py_InitMole("wmf",ExtestMethods);
PyObject*m;
m=PyMole_Create(&wmf_mole);
if(m==NULL){
returnNULL;
}
returnm;
}
『叄』 python調用c語言實現comtrade讀取
在處理大量數據時,通過Python調用C語言實現COMTRADE讀取可以顯著提高效率。具體配置如下:
使用環境包括Python版本3.8和Visual Studio版本2017。相較於使用Python獨立讀取COMTRADE文件,C語言實現的讀取方式表現出明顯優勢。
功能介紹主要集中在快速讀取COMTRADE文件的512個通道在10秒內的數據。測試結果表明,C語言的讀取效率遠超Python,耗時僅1.3秒,而Python獨立讀取需20-30秒,使用python自帶的pyComtrade模塊則需要200-300秒。這使得C語言在處理大規模數據時更顯卓越。
接下來是C語言讀取DAT文件的代碼示例,該代碼旨在高效讀取COMTRADE文件的數據。
Python代碼方面,通過調用C語言編寫的函數,可以實現COMTRADE文件的快速解析。這一過程不僅提升了數據處理速度,也節省了計算資源,是處理大規模數據時的優選方案。
『肆』 Python C API使用時需要注意什麼
一:用C API為Python寫C語言函數,以方便Python中調用
1. 首先實現一個特定原型的函數,用Python C API來實現的話,所有函數必須是這種原型。必須是類似這樣的
PyObject *Fun(PyObject *self, PyObject *args)
self應該是在用類的時候才會用到(我沒有用到),args就是函數的參數。因為args是一個PyObject*類型(可以代表Python語言中的任何類型)
2. 將參數轉換成C 語言表示的內容,用PyArg_ParseTuple函數。
3. 執行完需要的操作後,也必須返回一個PyObject*類型的值。通過Py_BuildValue函數來構建。
這里要說的是,假如希望返回一個Tuple類型的值,可以先用
PyObject *tuple = Py_BuildValue("(iis)", 1, 2, "three");
形式來構建,假如很多的話,可以用下面的方式來構建
PyObject *t;
t = PyTuple_New(3);
PyTuple_SetItem(t, 0, PyLong_FromLong(1L));
PyTuple_SetItem(t, 1, PyLong_FromLong(2L));
PyTuple_SetItem(t, 2, PyString_FromString("three"));
這一點在剛開始開工的時候迷惑了很久。
4. 將要輸出的所有函數放入一個數組中,數組的結構是:
struct PyMethodDef {
const char *ml_name; /* The name of the built-in function/method */
PyCFunction ml_meth; /* The C function that implements it */
int ml_flags; /* Combination of METH_xxx flags, which mostly
describe the args expected by the C func */
const char *ml_doc; /* The __doc__ attribute, or NULL */
};
數組以{NULL, NULL}結束
5. 構造一個Python import時初始化的函數
類似
PyMODINIT_FUNC
initexample(void)
{
Py_InitMole("example", example_methods);
}
這里有個特別需要注意的是,初始化函數名字有嚴格要求,init後面必須跟模塊名,否則Python找不到確定的函數會報沒有初始化函數的錯誤
擴展模塊寫完後,編譯成動態庫(Python要求此動態庫名字為pyd,實際就是改個後綴而已)。就可以直接在Python腳本中用import的方式載入了,對於使用來說,根本不需要知道此庫是用C API擴展寫的還是直接用Python語句寫的(這點Lua做的也是一樣好)
最後,python的源代碼中附帶了一個叫做example_nt的例子,可以參考一樣,完整的擴展代碼如下:
#include "Python.h"
static PyObject *
ex_foo(PyObject *self, PyObject *args)
{
printf("Hello, world/n");
Py_INCREF(Py_None);
return Py_None;
}
static PyMethodDef example_methods[] = {
{"foo", ex_foo, METH_VARARGS, "foo() doc string"},
{NULL, NULL}
};
PyMODINIT_FUNC
initexample(void)
{
Py_InitMole("example", example_methods);
}
二.C語言中調用Python語句
首先,void Py_Initialize()用來初始化,void Py_Finalize()用來結束Python的調用,這是必須要的。
燃火分兩種情況,假如僅僅是幾條語句的話,那麼以PyRun_為前綴的一些函數都很好用,比如
int PyRun_SimpleString(const char *command)
函數就可以直接執行一條char*的Python語句。
需要獲得返回值得話
PyObject* PyRun_String(const char *str, int start, PyObject *globals, PyObject *locals)
也很好用,以上兩個函數用來處理Python源代碼已經讀入內存的情況,在文件中的時候
int PyRun_SimpleFile(FILE *fp, const char *filename)
PyObject* PyRun_File(FILE *fp, const char *filename, int start, PyObject *globals, PyObject *locals)
使用類似。不多講了。
假如是個模塊的話(比如一個函數),希望在C語言中調用的話那麼使用起來就稍微復雜了一點。這種情況的需要在於你可以從C語言中向Python函數中傳入參數並且執行,然後獲取結果。
此處又分為幾種情況:
在文件中,在內存中,編譯過的,源代碼。
在文件中都很好解決,和上面一樣。這里主要講在內存中的情況。(事實上我工作中需要並且耗費了很長時間才找到解決方法的就是這種情況)
未編譯時:(也就是源代碼)
1.通過
PyObject* Py_CompileString(const char *str, const char *filename, int start)
API首先編譯一次。此API的參數我說明一下,str就是內存中的源代碼,filename主要是出錯時報錯誤用的,事實測試證明,你隨意給個字元串也沒有關系,但給NULL參數在運行時必然報錯。start我一般用的是Py_file_input,因為的確是從文件中讀取過來的,相對的還有Py_single_input用來表示一條語句,Py_eval_input的用法我也不是太清楚。
源代碼通過此函數調用後,獲得編譯後的PyObject*,(其實假如跟進源代碼中去看,是一個PyCodeObject結構)假設命名為lpCode。
2.此時再調用API
PyObject* PyImport_ExecCodeMole(char *name, PyObject *co)
導入模塊。參數也說明一下,name為導入的模塊名,co就是前面編譯過的代碼對象(lpCode)。返回的就是模塊對象了,假設命名為lpMod。
3.再調用API
PyObject* PyObject_GetAttrString(PyObject *o, const char *attr_name)
獲得函數對象。o就是模塊對象(lpMod),attr_name就是你想要調用的函數名了,假設叫main的函數,就是」main」,然後返回的就是函數對象,假設命名為lpFun。
4.此時可以用API
int PyCallable_Check(PyObject *o)
去檢查一下是不是獲得了一個函數。假如確定的話,就可以直接用
PyObject_Call開頭的一族函數調用lpFun了。這些函數包括很多,一般就是輸入參數的不同,但是效果都是一樣的,就是調用函數而已。參數一般可以通過前面說過的build函數來獲得,返回值也是獲得一個PyObject*,可以通過PyArg_那個函數來獲取,但是好像不太好,那是分析參數用的。推薦用確定類型(假設為type)的類似Py[type]_As的函數來獲取。
比如:
long PyLong_AsLong(PyObject *pylong)獲取long
double PyLong_AsDouble(PyObject *pylong)獲取double
這里想說的是,應該有直接從源代碼中獲取函數調用對象的方式,但是我本人沒有試出來,有人知道請一定賜教!
編譯過的代碼:
對於編譯過的代碼和上面就是獲得編譯後的PyCodeObject對象,當然在源代碼中表示還是PyObject*的方法不同(上例中的lpCode)。
當然要想以後獲得一個編譯後的lpCode,自然要先編譯一下啦。但是純粹編譯成pyc結尾的文件後,直接讀入內存,我沒有找到將其轉化為PyCodeObject對象的方法(也希望有人知道能告訴我!)
我找到的方法是先用
PyObject* PyMarshal_WriteObjectToString(PyObject *value, int version)
void PyMarshal_WriteLongToFile(long value, FILE *file, int version)
兩個函數先把PyCodeObject對象(lpCode)序列化到文件或者內存中。
再在需要的時候用函數
PyObject* PyMarshal_ReadObjectFromFile(FILE *file)
PyObject* PyMarshal_ReadObjectFromString(char *string, Py_ssize_t len)
讀出來,讀出來的PyObject*其實就是想要的PyCodeObject對象了(lpCode)。接下來的步驟與未編譯時的步驟一樣。
光是這個扭曲的方法我還是參考老總給的半邊資料反復研究出來的。而真正直接有效的方法我還是沒有找到。