====== 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);
}