c でpython module 作成
Cでpyton module
Cでpython module を作成する流れは下記の通り。
Cソース
#define PY_SSIZE_T_CLEAN #include <Python.h> static PyObject * spam_system( PyObject *self, PyObject *args) { const char *command; int sts; if (!PyArg_ParseTuple(args, "s", &command)) return NULL; sts = system(command); return PyLong_FromLong(sts); } static PyObject* hello ( PyObject *self, PyObject *args) { printf("How are you?\n"); Py_RETURN_NONE; } static PyObject* push( PyObject *self, PyObject *args){ PyObject *p_list, *inthert_val, *receive_list; if(!PyArg_ParseTuple(args, "O!i", &PyList_Type, &p_list, &inthert_val)) return NULL; receive_list = PySequence_List(p_list); printf("pushing %d\n", inthert_val); PyList_Append(receive_list, Py_BuildValue("i", inthert_val)); return receive_list; } static PyObject* pop ( PyObject *self, PyObject *args){ PyObject *p_list, *p_value; int size; long val; if(!PyArg_ParseTuple(args, "O!", &PyList_Type, &p_list)) return NULL; size = PyList_Size(p_list); p_value = PyList_GetItem(p_list, size - 1); val = PyLong_AsLong(p_value); printf("poping %d\n", val); return p_value; } static PyMethodDef pmethod[] = { {"spam_system", (PyCFunction) spam_system, METH_NOARGS, "primer: ststem"}, {"hello", (PyCFunction) hello, METH_NOARGS, "primer: hello"}, {"push", (PyCFunction) push, METH_VARARGS, "primer: push"}, {"pop", (PyCFunction)pop, METH_VARARGS, "primer: pop"}, {NULL, NULL, 0, NULL} }; static struct PyModuleDef pm = { PyModuleDef_HEAD_INIT, "primer", NULL, -1, pmethod }; PyMODINIT_FUNC PyInit_primer (void) { return PyModule_Create( &pm ); }
return NULLの所、大丈夫なのだろうか? python document でもNULLを返しているが、NULLとPy_RETURN_NONEの違いは? NULLはエラーらしい。例外処理に関しては、また後で。
- note: "Python.h" は下記をインクルード: <stdio.h> 、 <string.h> 、 <errno.h> 、 <stdlib.h>
初期化
int main(int argc, char *argv[]) { wchar_t *program = Py_DecodeLocale(argv[0], NULL); if ( program == NULL ) { fprintf(stderr, "Fatal error: cannot decode argv[0]\n"); exit(1); } /* Add a built-in module, before Py_Initialize */ PyImport_AppendInittab( "primer", PyInit_primer ); /* Pass argv[0] to the Python interpreter */ Py_SetProgramName( program ); /* Initialize the Python interpreter. Required. */ Py_Initialize(); /* Optionally import the module; alternatively, import can be deferred until the embedded script imports it. */ PyImport_ImportModule( "primer" ); ... PyMem_RawFree( program ); return 0; }
setup.py
Cソースをコンパイルするsetup.pyを作成する。
# python setup.py build_ext -i # setup.py from distutils.core import setup, Extension setup( name='primer', version='1.0', ext_modules=[ Extension('primer', ['primer.c']) ] )
コンパイル
python setup.py build_ext -i
モジュール利用
# python usecase import primer primer.hello() lista = primer.push([1, 2], 3) print(list) val = primer.pop(lista) print(val) 出力 How are you? pushing 3 [1, 2, 3] poping 3 3