‘壹’ 求帮忙把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)。接下来的步骤与未编译时的步骤一样。
光是这个扭曲的方法我还是参考老总给的半边资料反复研究出来的。而真正直接有效的方法我还是没有找到。