1. 程式人生 > >用C語言擴充套件Python

用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\n",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系統試一下

得到最大的教訓就是這本書要粗看,細看害死人啊。