====== PythonのクラスオブジェトCの関数に渡す ====== 作成日: 2023-08-04 (金) [[https://youtu.be/kYp_yQfunhU|第3回 Python/C APIに触れてみる (2)]] ===== ソースコード ===== ==== setup.py ==== from setuptools import setup, Extension setup( name="pointlib", ext_modules=[ Extension("pointlib", ["pointlibmodule.c"]) ] ) ==== point.py ==== class Point: def __init__(self, x, y): self.x = x self.y = y def to_s(self): return "({}, {})".format(self.x, self.y) ==== pointlibmodule.c ==== #define PY_SSIZE_T_CLEAN #include #include static PyObject *pointlib_distance(PyObject *self, PyObject *args) { PyObject *point_obj = NULL; if (!PyArg_ParseTuple(args, "O", &point_obj)) { return NULL; } PyObject *x_obj = PyObject_GetAttrString(point_obj, "x"); if (x_obj == NULL) { return NULL; } PyObject *y_obj = PyObject_GetAttrString(point_obj, "y"); if (y_obj == NULL) { Py_XDECREF(x_obj); return NULL; } long x = PyLong_AsLong(x_obj); long y = PyLong_AsLong(y_obj); Py_XDECREF(y_obj); Py_XDECREF(x_obj); return PyFloat_FromDouble(sqrt(x * x + y * y)); } // clang-format off static PyMethodDef pointlib_methods[] = { {"distance", pointlib_distance, METH_VARARGS, "Distance from origin to the point."}, {NULL, NULL, 0, NULL} }; static PyModuleDef pointlib_module = { PyModuleDef_HEAD_INIT, "pointlib", "Example for passing a Python object to C function.", -1, pointlib_methods }; // clang-format on PyMODINIT_FUNC PyInit_pointlib(void) { return PyModule_Create(&pointlib_module); }