void get_str(int i, char** tmp){ sprintf(*tmp,"%d",i); }
PyObject* ta_get_str(PyObject *self, PyObject *args, PyObject *kwargs) { char* tmp; int i; static char* keywords[] = { "i",NULL }; if (!PyArg_ParseTupleAndKeywords(args, kwargs, "i", keywords, &i)) { return NULL; } get_str(i,&tmp); // Py_RETURN_NONE; return PyBytes_FromString(tmp); }
import ta res=ta.get_str(3) res.decode('utf-8') '3'
PyObject *ta_system(PyObject *self, PyObject *args) { const char *command; int sts; if (!PyArg_ParseTuple(args, "s", &command)) return NULL; //system是C自带函数,不需要再自定义了 sts = system(command); if (sts < 0) { PyErr_SetString(PyExc_ValueError, "System command failed"); return NULL; } return PyLong_FromLong(sts); }
void print_str(const char *s1,const char *s2){ printf("%s,%s\n",s1,s2); }
PyObject *ta_print_str(PyObject *self, PyObject *args, PyObject *kwargs) { /* Shared references that do not need Py_DECREF before returning. */ PyObject *obj = NULL; int number = 0; char* s1; char* s2; /* Parse positional and keyword arguments */ static char* keywords[] = { "s1", "s2", NULL }; if (!PyArg_ParseTupleAndKeywords(args, kwargs, "ss", keywords, &s1, &s2)) { return NULL; } /* Function implementation starts here */ print_str(s1,s2); if (number < 0) { PyErr_SetObject(PyExc_ValueError, obj); return NULL; /* return NULL indicates error */ } Py_RETURN_NONE; }
ta.c
#include <stdio.h> #include <stdlib.h> //-----------head.h start --------------- #ifndef _TA_H_ #define _TA_H_ void print_str(const char *s1,const char *s2); #endif //-----------head.h end --------------- //-----------ta.c start --------------- void print_str(const char *s1,const char *s2){ printf("%s,%s\n",s1,s2); } //-----------ta.c end --------------- #include <Python.h> #include <stdio.h> /* * Implements an example function. */ PyDoc_STRVAR(ta_print_str_doc, "print_str(ss) Example function"); PyDoc_STRVAR(ta_system_doc, "system(cmd) Example function"); PyObject *ta_print_str(PyObject *self, PyObject *args, PyObject *kwargs) { /* Shared references that do not need Py_DECREF before returning. */ PyObject *obj = NULL; int number = 0; char* s1; char* s2; /* Parse positional and keyword arguments */ static char* keywords[] = { "s1", "s2", NULL }; if (!PyArg_ParseTupleAndKeywords(args, kwargs, "ss", keywords, &s1, &s2)) { return NULL; } /* Function implementation starts here */ print_str(s1,s2); if (number < 0) { PyErr_SetObject(PyExc_ValueError, obj); return NULL; /* return NULL indicates error */ } Py_RETURN_NONE; } PyObject *ta_system(PyObject *self, PyObject *args) { const char *command; int sts; if (!PyArg_ParseTuple(args, "s", &command)) return NULL; //system是C自带函数,不需要再自定义了 sts = system(command); if (sts < 0) { PyErr_SetString(PyExc_ValueError, "System command failed"); return NULL; } return PyLong_FromLong(sts); } /* * List of functions to add to ta in exec_ta(). */ static PyMethodDef ta_functions[] = { { "print_str", (PyCFunction)ta_print_str, METH_VARARGS | METH_KEYWORDS, ta_print_str_doc }, { "system", (PyCFunction)ta_system, METH_VARARGS | METH_KEYWORDS, ta_print_str_doc }, { NULL, NULL, 0, NULL } /* marks end of array */ }; /* * Initialize ta. May be called multiple times, so avoid * using static state. */ int exec_ta(PyObject *module) { PyModule_AddFunctions(module, ta_functions); PyModule_AddStringConstant(module, "__author__", "tanpf"); PyModule_AddStringConstant(module, "__version__", "1.0.0"); PyModule_AddIntConstant(module, "year", 2023); return 0; /* success */ } /* * Documentation for ta. */ PyDoc_STRVAR(ta_doc, "The ta module"); static PyModuleDef_Slot ta_slots[] = { { Py_mod_exec, exec_ta }, { 0, NULL } }; static PyModuleDef ta_def = { PyModuleDef_HEAD_INIT, "ta", ta_doc, 0, /* m_size */ NULL, /* m_methods */ ta_slots, NULL, /* m_traverse */ NULL, /* m_clear */ NULL, /* m_free */ }; PyMODINIT_FUNC PyInit_ta() { return PyModuleDef_Init(&ta_def); }
setup_py38.py
from distutils.core import setup, Extension setup(name='ta', version='1.0', \ ext_modules=[Extension('ta', ['ta.c'])])
编译安装
(base) [xt@ai1 python]$ cd ta/ (base) [xt@ai1 ta]$ ls build dist setup_py38.py ta.c ta.egg-info ... ... ... Installed /home/xt/anaconda3/lib/python3.9/site-packages/ta-1.0-py3.9-linux-x86_64.egg Processing dependencies for ta==1.0 Finished processing dependencies for ta==1.0
调用
>>> import ta >>> status = ta.system("pwd") /opt/tpf/cwks/python/ta >>> status 0 >>> ta.print_str('a','b') a,b
setup.py
from distutils.core import setup, Extension setup(name='ta', version='1.2', \ ext_modules=[Extension('ta', ['ta.c'])])
编译安装
python setup.py install
几个注意事项
ta.c 是最全的文件, C中可通过#include引用一堆文件,不必写这些引用的文件,只需要写上最全的文件即可 编辑安装不生效 明明修改了文件,但却没效果,可以尝试删除自动的build,dist目录,再次编辑 如果还不生效,就多改变一些C代码,比如增加一个方法等, 下次再不生效时,再把增加的这个无用方法注释掉, 大量的代码变动会迫使其重新编译
Extending Python with C or C++ pyobject的各种类型 PyFloatObject PyTupleObject PyListObject c返回字符串