C 擴展python ,簡單例子,實現加法

首先編寫LGadd_model.cpp

#define PY_SSIZE_T_CLEAN
#include "Python.h"
/*由於 Python 可能會定義一些能在某些系統上影響標準頭文件的預處理器定義,
因此在包含任何標準頭文件之前,你 必須 先包含 Python.h。
推薦總是在 Python.h 前定義 PY_SSIZE_T_CLEAN 。查看 提取擴展函數的參數 來了解這個宏的更多內容
https://docs.python.org/zh-cn/3.7/extending/extending.html#parsetuple
*/

// c++ 實現加法,傳入倆個int型,輸出和.
int add(int a, int b){
    return a+b;
};

/*模塊中每個可供Python調用的函數都需要一個對應的包裹函數*/
static PyObject *LG_add(PyObject * self, PyObject *args){
    /*self參數指向模塊對象對於對象實例則指向方法。
      args參數是指向一個Python的tuple對象的指針,其中包含參數,
      每個tuple項對應一個調用參數。 這些參數也全都是Python對象,
      在C函數中使用它們需要先將其轉換爲C值*/
    int a,b;

    /*Python API 中的函數PyArg_ParseTuple()會檢查參數類型並將其轉換爲C值,
      這裏 'ii' 表示倆個整型*/
    if (!PyArg_ParseTuple(args,"ii",&a,&b)) {
          return NULL;
    }
    return (PyObject*)Py_BuildValue("i",add(a,b));
    /* 這裏返回的值,必須這麼寫,返回的是一個python對象,而不能直接是C對象.*/
};

// 定義一個方法表,方法表中可以包含多個方法
static PyMethodDef LGMethods[] = {
    /* "add" 最終在python中模塊調用的方法名,
       LG_add, 這是對應的C++ 程序的方法名,
       也就是python中 使用  模塊.add 調用 C++ 中的LG_add函數*/
    {"add",  LG_add, METH_VARARGS},
    {NULL, NULL}        /* Sentinel */
};

// 定義模塊結構 引用方法表
static struct PyModuleDef LGmodule = {
    PyModuleDef_HEAD_INIT,
    "LG",   /* 模塊的名字 */
    NULL, /* module documentation, may be NULL */
    -1,       /* size of per-interpreter state of the module,
                 or -1 if the module keeps state in global variables. */
    LGMethods /*模塊方法表*/
};

/*模塊初始化函數必須命名爲PyInit_name(),其中name是模塊的名字,並應該定義爲非static.
  模塊結構必須傳遞給解釋器的模塊初始化函數*/
PyMODINIT_FUNC
PyInit_LG(void){
    return PyModule_Create(&LGmodule);
}

/*需要特別注意 文件各方法名稱的對應關係,必須完全對應*/

編寫 setup.py文件

from distutils.core import setup,Extension

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

運行進行編譯

python setup.py build

 輸出:

running build
running build_ext
building 'LG' extension
gcc -pthread -B /home/XXX/anaconda3/compiler_compat -Wl,--sysroot=/ -Wsign-compare -DNDEBUG -g -fwrapv -O3 -Wall -Wstrict-prototypes -fPIC -I/home/XXX/anaconda3/include/python3.7m -c cal_ids.cpp -o build/temp.linux-x86_64-3.7/cal_ids.o
cc1plus: warning: command line option ‘-Wstrict-prototypes’ is valid for C/ObjC but not for C++
creating build/lib.linux-x86_64-3.7
g++ -pthread -shared -B /home/XXX/anaconda3/compiler_compat -L/home/XXX/anaconda3/lib -Wl,-rpath=/home/XXX/anaconda3/lib -Wl,--no-as-needed -Wl,--sysroot=/ build/temp.linux-x86_64-3.7/cal_ids.o -o build/lib.linux-x86_64-3.7/LG.cpython-37m-x86_64-linux-gnu.so

運行進行安裝

python setup.py install

輸出:

running install
running bdist_egg
running egg_info
creating LG.egg-info
writing LG.egg-info/PKG-INFO
writing dependency_links to LG.egg-info/dependency_links.txt
writing top-level names to LG.egg-info/top_level.txt
writing manifest file 'LG.egg-info/SOURCES.txt'
reading manifest file 'LG.egg-info/SOURCES.txt'
writing manifest file 'LG.egg-info/SOURCES.txt'
installing library code to build/bdist.linux-x86_64/egg
running install_lib
running build_ext
creating build/bdist.linux-x86_64
creating build/bdist.linux-x86_64/egg
copying build/lib.linux-x86_64-3.7/LG.cpython-37m-x86_64-linux-gnu.so -> build/bdist.linux-x86_64/egg
creating stub loader for LG.cpython-37m-x86_64-linux-gnu.so
byte-compiling build/bdist.linux-x86_64/egg/LG.py to LG.cpython-37.pyc
creating build/bdist.linux-x86_64/egg/EGG-INFO
copying LG.egg-info/PKG-INFO -> build/bdist.linux-x86_64/egg/EGG-INFO
copying LG.egg-info/SOURCES.txt -> build/bdist.linux-x86_64/egg/EGG-INFO
copying LG.egg-info/dependency_links.txt -> build/bdist.linux-x86_64/egg/EGG-INFO
copying LG.egg-info/top_level.txt -> build/bdist.linux-x86_64/egg/EGG-INFO
writing build/bdist.linux-x86_64/egg/EGG-INFO/native_libs.txt
zip_safe flag not set; analyzing archive contents...
__pycache__.LG.cpython-37: module references __file__
creating dist
creating 'dist/LG-0.0.0-py3.7-linux-x86_64.egg' and adding 'build/bdist.linux-x86_64/egg' to it
removing 'build/bdist.linux-x86_64/egg' (and everything under it)
Processing LG-0.0.0-py3.7-linux-x86_64.egg
creating /home/XXX/anaconda3/lib/python3.7/site-packages/LG-0.0.0-py3.7-linux-x86_64.egg
Extracting LG-0.0.0-py3.7-linux-x86_64.egg to /home/XXX/anaconda3/lib/python3.7/site-packages
Adding LG 0.0.0 to easy-install.pth file

Installed /home/XXX/anaconda3/lib/python3.7/site-packages/LG-0.0.0-py3.7-linux-x86_64.egg
Processing dependencies for LG==0.0.0
Finished processing dependencies for LG==0.0.0

最終在python文件中就可以調用

import LG

a = 1
b =2

print(LG.add(a,b))

在調用時, 雖然LG模塊 顯示No module named LG

但是可以正常使用

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