用c++擴展python(一)簡單實現

藉助官方的說明文檔:

https://docs.python.org/2/extending/index.html

https://docs.python.org/zh-cn/3.8/extending/extending.html

 

我們的目標是實現一個Extend的模塊,模塊中有一個add函數,:

import Exten

print(Exten(1,2))

1.C++文件編寫

通過生成一個如下的Extend.cpp文件:

#include "Python.h"

int add(int a, int b){
        return a + b;
}

/* 函數調用*/
static PyObject *Exten_add(PyObject *self, PyObject *args){
        int a,b;

        if(!PyArg_ParseTuple(args, "ii", &a, &b)){
                return NULL;
        }
        //如果所有參數都具有正確的c的相應類型,並且其參數存儲在傳遞其地址的變量中。PyArg_ParseTuple>返回true
        return (PyObject *)Py_BuildValue("i",add(a,b));
        // "i"表示傳參類型爲int
        //如果沒有返回值的話,c返回void應變成python的none,改成以下語句:
        //Py_INCREF(Py_None);return Py_None;
}
/*定義調用的函數名*/
static PyMethodDef ExtenMethods[]={
        {"add", Exten_add, METH_VARARGS},
        {NULL, NULL}
        /*{"add"是python中使用的名字,函數,METH_VARARGS是給解釋器C的標識}*/   
};
static struct PyModuleDef ExtenModule = {
        PyModuleDef_HEAD_INIT,
        "Exten",     /* m_name*/
        NULL,        /* m_doc*/
        -1,                  /* m_size*/
        ExtenMethods /* m_methods*/
};

/* 初始化模>塊 PyInit_name*/
PyMODINIT_FUNC
PyInit_Exten(){
        PyObject *m = NULL;
        m = PyModule_Create(&ExtenModule);
        //m = Py_InitModule("spam", SpamMethods);
        if(m == NULL)
                return NULL;
}

在傳參時注意python中和C中對象的轉換。

 

https://docs.python.org/2/c-api/index.html

 

2.創建擴展模塊

使用擴展前:需要(1)編譯,(2)與Python系統鏈接

我們可以選擇兩種方法來進行擴展:

1.將 C++ 語言程序編譯成一個擴展模塊,生成擴展文件,linux下是.so,windows下是.dll,

需要指定 Python.h 頭文件所在的路徑,和鏈接 python2.7 等庫文件(-lpython2.7),例外需加上指令 -fPIC -shared 以指導其編譯成一個動態鏈接庫。編譯使用類似下面的命令(注意將其中的頭文件路徑改成你的系統中實際的路徑)

gcc -I/public/home/yinghuang/software/anaconda3/include/python3.8  -o Exten.so Exten.cpp -fPIC -shared -lpthread -ldl -lutil -lm

獲取Python.h頭文件,可以在命令行中輸入以下命令獲得:

$ python -c "import sysconfig; print( sysconfig.get_path('include') )"

 

2.通過Distutils在Python環境中構建和安裝模塊

在同一目錄下建立setup.py

from distutils.core import setup,Extension

MOD = 'Exten' #模塊名
setup(name=MOD,ext_modules=[Extension(MOD,sources=['Exten.cpp'])])

在命令行中輸入: 

python setup.py build
python setup.py install

這樣就可以將模塊安裝成功了。

 

參考鏈接:

https://www.jianshu.com/p/558d4f3e4bfb

https://www.jianshu.com/p/eb2618067eae

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章