用C语言扩展Python

Posted AcodingDog

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了用C语言扩展Python相关的知识,希望对你有一定的参考价值。

最近一直在跟随《PYTHON核心编程》学习一些python的编写,可惜的是这本书的版本太过于陈旧。大部分范例代码都是python2的版本。

刚刚在看python用C语言写扩展包的时候踩到了一个大坑,到现在没用爬上来

跟其他的python代码一样,扩展包也无非就是调包而已,要把python的数据类型转换成C语言能够兼容的数据类型,

通过C程序进行运算后,再返回成python自己的数据类型。

这里在写C程序的时候需要用到Python.h的头文件。这个一般在python所在的文件夹下。

我直接暴力拷贝到了MinGW的include目录下

Python3和Python2的写法在这里已经完全不一样了,可以参考

https://www.tutorialspoint.com/python/python_further_extensions.htm

以下是我的代码,不过失败了(苦笑)

#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <Python.h>
#define BUFFSIZE 1000

int fact(int n){
    if(n < 2){
        return 1;
    }
    return fact(n - 1) + fact(n - 2);
}

char* reverseString(char *origin){
     char temp;
     int length = strlen(origin);
     int end = strlen(origin)-1;
     int start = 0;
     printf("%s
",origin);
     while (start <= end){
         temp = origin[start];
         origin[start] = origin[end];
         origin[end] = temp;
         start++;
         end--;
     }
     return origin;
}
static PyObject *ExtEx_fact(PyObject *self, PyObject *args){
    int num;    //Hold arguments of fact()
    if(!PyArg_ParseTuple(args, "i", &num)){    //parse python‘s args into C‘s int args("i")
        return NULL;
    }
    return (PyObject*)Py_BuildValue("i", fact(num));
}
static PyObject *ExtEx_reverse(PyObject *self, PyObject *args){
    char *string;
    char *temp;
    PyObject *result;
    if(!PyArg_ParseTuple(args, "s", &string)){
        return NULL;
    }
    result = (PyObject *)Py_BuildValue("ss", string, temp=reverseString(strdup(string)));
    free(temp);
    return result;
}
static PyMethodDef ExtExMethods[] = {
    {"fact", ExtEx_fact, METH_VARARGS},
    {"reverseString", ExtEx_reverse, METH_VARARGS},
    {NULL, NULL},
};
static struct PyModuleDef ExtEx = {
    PyModuleDef_HEAD_INIT,
    "ExtEx",
    NULL,
    -1,
    ExtExMethods,
    NULL,
    NULL,
    NULL,
    NULL
};
void initExtEx(){
    PyModule_Create(&ExtEx);
}

需要用到setup的python脚本进行编译

from distutils.core import setup, Extension
setup(name=ExtEx, version=1.0,        ext_modules=[Extension(ExtEx, [ExtEx.c])])

不过遇到了一个错误信息

error: Unable to find vcvarsall.bat

好像解决起来非常麻烦,可以参考StackOverflow的这个帖子

https://stackoverflow.com/questions/2817869/error-unable-to-find-vcvarsall-bat

这个帖子里第二个回答非常有用。

但是结果依旧不行,等有时间用Linux系统试一下

得到最大的教训就是这本书要粗看,细看害死人啊。

以上是关于用C语言扩展Python的主要内容,如果未能解决你的问题,请参考以下文章

python C语言扩展之简单扩展-使用ctypes访问C代码

python怎么作为c语言的扩展

使用C语言扩展Python

Python Cookbook(第3版)中文版:15.10 用Cython包装C代码

如何实现 C/C++ 与 Python 的通信

几段代码,让你用递归解决C语言扩展排雷(扫雷)