当前位置:首页>正文

有没有能把python代码转换为c语言代码的工具 如何让python调用C和C 代码

2023-04-14 23:20:10 互联网 未知

有没有能把python代码转换为c语言代码的工具

C 兼容C语言,但C语言不可能兼容C
所以,C 代码直接转是转不了C的。
只能从逻辑上,对C 的许多语法进行代码上的重新实现。
比如将对象转换为结构体,将对象封装的函数修改为独立函数,增加对象参数。
将重载去掉,而是根据需要调用非重载的不同名的函数。
总之来说,硬要将C 转为C实现的话,那代码重写的工作是避免不了的。

如何让python调用C和C 代码

要搞明白如何让python调用C/C 代码(也就是写python的extension),你需要征服手册中的<>厚厚的一章。在昨天花了一个小时看地头晕脑胀,仍然不知道如何写python的extension后,查阅了一些其他书籍,最终在<>书中找到了教程。 1. 首先要明白的是,所谓的python扩展(也就是你提供给python的c/c 代码,不一定是c/c 代码,可以是其他语言写的代码)是一个dll,并且这个dll放在本机python安装目录下的DLLs目录下(譬如我机器上的路径是:F:/Program Files/Python25/DLLs),假如我们接下来要写的扩展module名为mb,python调用的代码为:import mbmb.showMsg("Pythons 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一些定义的头文件,在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("Pythons 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_InitModule("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 module", MB_ICONINFORMATION | MB_OK)//返回值return Py_BuildValue("i", r)}将上面这段混杂着大量注释的代码拷贝到你的编辑器里,然后编译生成mb.dll,修改后缀成mb.pyd,然后拷贝到python的DLLs目录下,打开idle(python的交互程序),写入代码:import mbmb.showMsg("Pythons really amazing, I kindda love it!")

python扩展的c代码在哪里写

在哪里写都可以啊,重要的是编译过程。给你介绍下编译过程吧。


在windows和linux下面,对C扩展的编译方法是不一样的,我们先来看windows版的。
我们用C实现一个简单的加法。
首先新建一个文件add.c,代码如下:
#include 
static PyObject* add(PyObject *self, PyObject *args) 
//一定声明为static,把他们限制在这个文件范围里。 几乎所有的参数都是PyObject类型,在python,每个东西都是object。 
static PyObject* add(PyObject* self, PyObject* args) 

    int x=0  
    int y=0
    int z=0
    if (! PyArg_ParseTuple(args, "i|i", &x, &y))
        return NULL
    /*第一个参数是self,这个是python用的, 每个函数都要有。我们暂时不管。args是一个参数列表。她把所有的参数都整合成一个string。所以 
      我们需要从这个string里来解析我们的参数。PyArg_ParseTuple来完成这个任务。第一个参数是args, 就是我们要转换的参数。第二个是格式符号。
      “s”代表是个string。 从args里提取一个参数就写"s", 两个的话就写"s|s", 如果是一个string,一个int,就写"s|i", 和printf差不多。第三个
      参数就是提取出来的参数放置的真正位置。必须传递这个参数的地址。对于add, 他将提取两个参数。分别是x和y。*/
    z=x y
    return Py_BuildValue("i", z)
    /*调用完之后我们需要返回结果。这个结果是c的type或者是我们自己定义的类型。必须把他转换成PyObject, 让python认识。这个用Py_BuildValue 
      来完成。他是PyArg_ParseTuple的逆过程。他的第一个参数和PyArg_ParseTuple的第二个参数一样, 是个格式化符号。第三个参数 
      是我们需要转换的参数。Py_BuildValue会把所有的返回只组装成一个tutple给python。*/

static PyMethodDef addMethods[] =

    {"add",  add, METH_VARARGS, "Execute a shell command."}, 
    {NULL, NULL, 0, NULL}

/*这个是一个c的结构。他来完成一个映射。 我们需要把我们扩展的函数都映射到这个表里。表的第一个字段是python真正认识的。是python  里的方法名字。 第二个字段是python里的这个方法名字的具体实现的函数名。 在python里调用add, 真正执行的是用c写的add函数。第三个字段是METH_VARARGS, 他告诉python,add是调用c函数来实现的。第四个字段是这个函数的说明。如果你在python里来help这个函数,将显示这个说明。相当于在python里的函数的文档说明。*/
PyMODINIT_FUNC initadd() 

    Py_InitModule("add", addMethods) 

/*注意,这个函数的名字不能改动。 必须是init 模块名字。 我们的模块名字是add。所以这个函数是initadd()。
  这样python在导入add 的模块时候,才会找到这个函数,并调用。这个函数调用Py_InitModule来将模块名字和映射表结合在一起。 他表示,add这个模块使用addMethods这个映射表。python应该这样导入我们的module的.*/新建一个setup.py,内容如下:
from distutils.core import setup, Extension 
module1 = Extension(add, sources = [add.c]) 
setup (name = PackageName, version = 1.0, description = This is a demo package, ext_modules= [module1])组建:(由于我的机器上装了mingw,所以指定了mingw32。默认的编译器是vs2008。参考:
python setup.py build --compiler=mingw3执行后会在当前目录生成一个build目录及文件:
buildlib.win32-2.6add.pyd
将add.pyd拷贝到当前目录,并写一个测试文件test.py,代码如下:
import add
print add.add(3,4)
执行一下,输出为OK,基本上就是如此了。
在linux下的话,会有少许不同.
即直接用makefile将add.c编译成.so,python可以直接import,makefile代码如下:
PYLIB = /usr/bin
PYINC = /usr/include/python2.all: add.c
        gcc add.c -g -I$(PYINC) -shared -L$(PYLIB) -lpython2.6 -o add.so
clean:
        rm -f add.so用同样的测试代码,可以测试通过。