手记

C语言扩展Python

一、环境

              python2.6

             centos6.5


二、编写C文件(Extest2.c)

       

        #include <stdio.h> 
        #include <stdlib.h> 
        #include <string.h> 
 
        int fac(int n) 
        { 
            if(n<2) return 1; 
            return n*fac(n-1); 
         }  
  
         char *reverse(char *s) 
         { 
             register char t,*p=s,*q=(s+strlen(s)-1); //register变量作用参考https://blog.csdn.net/franz_/article/details/49427933
             while(s && (p<q)) 
             { 
                 t=*p; 
                 *p++=*q; //++和*优先级参考https://blog.csdn.net/nyzhl/article/details/1777577
                 *q--=t; 
             } 
             return s; 
         } 
  
         #include "Python.h" 
 
         static PyObject* 
         Extest_fac(PyObject* self,PyObject* args) 
         { 
             int num; 
             if(!(PyArg_ParseTuple(args,"i",&num))) //类似sscanf,接收python参数,按照指定格式转化,保存在一个地址中
                     return NULL; 
             return (PyObject*)Py_BuildValue("i",fac(num)); //将数值按照指定格式转换成输出类型
         } 
  
         static PyObject* 
         Extest_doppel(PyObject* self,PyObject* args) 
         { 
             char* orig_str; 
             char* dupe_str; 
             PyObject* retval; 
      
             if(!PyArg_ParseTuple(args,"s",&orig_str)) 
                 return NULL; 
             retval= (PyObject*)Py_BuildValue("ss",orig_str,dupe_str=reverse(strdup(orig_str))); //多种格式的书写ss,c语言支持运算后赋值,多步合成一个语句,比如链式操作.关于strdup函数参考https://www.cnblogs.com/the-tops/p/5891499.html
            free(dupe_str); //和strdup连用
            return retval; 
 } 
  
static PyMethodDef 
 ExtestMethods[]= 
 { 
     {"fac",Extest_fac,METH_VARARGS}, 
     {"doppel",Extest_doppel,METH_VARARGS}, 
     {NULL,NULL}, 
 }; //PyMethodDef SpamMethods数组定义了需要导出到Python中的名字,函数指针,参数类型,描述信息。注意第三个参数,标志了函数的参数类型。
METH_VARARGS代表的就是我们写Python时的*args,而METH_KEYWORDS就是Python中的**kwargs,所谓的字典字典变量。描述信息就在Python中就是DocString了。[引用自https://blog.csdn.net/yueguanghaidao/article/details/11538433]
  
 void initExtest() 
 { 
     Py_InitModule("Extest",ExtestMethods); //Extest是模块名,用于在python环境中导入 import Extest
 }

       以上的过程是首先声明c语言环境下参数类型,然后用PyArg_ParseTuple函数进行转换到声明中得到实例化后的参数,将这些参数运用到已经定义的函数中进行操作,依据操作后的返回值再进行转换输出.关于PyArg_ParseTuple转化格式参考http://web.mit.edu/people/amliu/vrut/python/ext/parseTuple.html


三、编译运行

    1.编写一个python脚本setup.py:

             #! /usr/bin/env python
            from distutils.core import setup,Extension
            setup(name="Extest",ext_modules=[Extension(MOD,sources=['Extest2.c'])])

     2.编译setup.py:

            python setup.py build

            此过程可能会遇到下面错误:其一找不到文件或者命令,解决方法:由于centos6.3之后默认没有安装gcc,因此使用命                            令  yum install gcc. 其二找不到Python.h头文件,解决方法:yum install python-devel。正确运行后结果如下:

                  

           这样在当前目录下会生成build目录,里面有两个目录如下:

                    

            在lib.linux-x86_64-2.6中含有Extest.so文件,只要将该文件复制到 /usr/lib64/python2.6/site-packages中即可在python导入

    3.安装模块

            除了手动复制到指定目录外,还可以使用命令执行

                    python setup.pu install

                正确执行后:

                    

                这样就将Exteset模块导入到默认查找路径中


四、测试

        

:~

原文出处

0人推荐
随时随地看视频
慕课网APP