youtube:python-mixing-003x2
差分
このページの2つのバージョン間の差分を表示します。
両方とも前のリビジョン前のリビジョン | |||
youtube:python-mixing-003x2 [2024/02/28 18:26] – 削除 - 外部編集 (不明な日付) 127.0.0.1 | youtube:python-mixing-003x2 [2024/02/28 18:26] (現在) – ↷ toybox:python-mixing-003x2 から youtube:python-mixing-003x2 へページを移動しました。 freemikan | ||
---|---|---|---|
行 1: | 行 1: | ||
+ | ====== CでPythonのクラスを作る ====== | ||
+ | |||
+ | 作成日: 2023-08-04 (金) | ||
+ | |||
+ | [[https:// | ||
+ | |||
+ | ===== ソースコード ===== | ||
+ | |||
+ | ==== setup.py ==== | ||
+ | |||
+ | <file python> | ||
+ | from setuptools import setup, Extension | ||
+ | |||
+ | setup( | ||
+ | name=" | ||
+ | ext_modules=[ | ||
+ | Extension(" | ||
+ | ] | ||
+ | ) | ||
+ | </ | ||
+ | |||
+ | ==== pointlibmodule.c ==== | ||
+ | |||
+ | <file c> | ||
+ | #define PY_SSIZE_T_CLEAN | ||
+ | #include < | ||
+ | #include < | ||
+ | |||
+ | // clang-format off | ||
+ | typedef struct { | ||
+ | PyObject_HEAD | ||
+ | double x; | ||
+ | double y; | ||
+ | } PointObject; | ||
+ | // clang-format on | ||
+ | |||
+ | static int Point_init(PointObject *self, PyObject *args) { | ||
+ | double x, y; | ||
+ | if (!PyArg_ParseTuple(args, | ||
+ | return -1; | ||
+ | } | ||
+ | self->x = x; | ||
+ | self->y = y; | ||
+ | return 0; | ||
+ | } | ||
+ | |||
+ | static PyObject *Point_to_s(PointObject *self, PyObject *Py_UNUSED(ignored)) { | ||
+ | char buf[1024]; | ||
+ | snprintf(buf, | ||
+ | return PyUnicode_FromFormat(" | ||
+ | } | ||
+ | |||
+ | static PyMemberDef Point_members[] = { | ||
+ | {" | ||
+ | {" | ||
+ | {NULL}}; | ||
+ | |||
+ | static PyMethodDef Point_methods[] = { | ||
+ | {" | ||
+ | {NULL, NULL, 0, NULL}}; | ||
+ | |||
+ | static PyTypeObject PointType = { | ||
+ | PyVarObject_HEAD_INIT(NULL, | ||
+ | .tp_doc = PyDoc_STR(" | ||
+ | .tp_basicsize = sizeof(PointObject), | ||
+ | .tp_itemsize = 0, | ||
+ | .tp_flags = Py_TPFLAGS_DEFAULT, | ||
+ | .tp_new = PyType_GenericNew, | ||
+ | .tp_init = (initproc)Point_init, | ||
+ | .tp_members = Point_members, | ||
+ | .tp_methods = Point_methods, | ||
+ | }; | ||
+ | |||
+ | static PyObject *pointlib_distance(PyObject *self, PyObject *args) { | ||
+ | PyObject *pt1, *pt2; | ||
+ | |||
+ | if (!PyArg_ParseTuple(args, | ||
+ | return NULL; | ||
+ | } | ||
+ | |||
+ | PyObject *x1_obj = PyObject_GetAttrString(pt1, | ||
+ | PyObject *y1_obj = PyObject_GetAttrString(pt1, | ||
+ | PyObject *x2_obj = PyObject_GetAttrString(pt2, | ||
+ | PyObject *y2_obj = PyObject_GetAttrString(pt2, | ||
+ | |||
+ | if (x1_obj == NULL || y1_obj == NULL || x2_obj == NULL || y2_obj == NULL) { | ||
+ | Py_XDECREF(x1_obj); | ||
+ | Py_XDECREF(y1_obj); | ||
+ | Py_XDECREF(x2_obj); | ||
+ | Py_XDECREF(y2_obj); | ||
+ | return NULL; | ||
+ | } | ||
+ | |||
+ | double x1 = PyFloat_AsDouble(x1_obj); | ||
+ | double y1 = PyFloat_AsDouble(y1_obj); | ||
+ | double x2 = PyFloat_AsDouble(x2_obj); | ||
+ | double y2 = PyFloat_AsDouble(y2_obj); | ||
+ | double dx = x2 - x1; | ||
+ | double dy = y2 - y1; | ||
+ | double dist = sqrt(dx * dx + dy * dy); | ||
+ | |||
+ | Py_DECREF(x1_obj); | ||
+ | Py_DECREF(y1_obj); | ||
+ | Py_DECREF(x2_obj); | ||
+ | Py_DECREF(y2_obj); | ||
+ | |||
+ | return PyFloat_FromDouble(dist); | ||
+ | } | ||
+ | |||
+ | static PyMethodDef pointlib_methods[] = { | ||
+ | {" | ||
+ | | ||
+ | {NULL, NULL, 0, NULL}}; | ||
+ | |||
+ | static PyModuleDef pointlib_module = { | ||
+ | PyModuleDef_HEAD_INIT, | ||
+ | .m_name = " | ||
+ | .m_doc = PyDoc_STR(" | ||
+ | .m_size = -1, | ||
+ | .m_methods = pointlib_methods, | ||
+ | }; | ||
+ | |||
+ | PyMODINIT_FUNC PyInit_pointlib(void) { | ||
+ | if (PyType_Ready(& | ||
+ | return NULL; | ||
+ | } | ||
+ | |||
+ | PyObject *module = PyModule_Create(& | ||
+ | if (module == NULL) { | ||
+ | return NULL; | ||
+ | } | ||
+ | |||
+ | Py_INCREF(& | ||
+ | if (PyModule_AddObject(module, | ||
+ | Py_DECREF(& | ||
+ | Py_DECREF(module); | ||
+ | return NULL; | ||
+ | } | ||
+ | |||
+ | return module; | ||
+ | } | ||
+ | </ | ||