我是Python / C API的新手,虽然我可以使用一些基本功能,但我仍在为此而苦苦挣扎。
PyObject* sum_elements(PyObject*, PyObject *o)
{
Py_ssize_t n = PyList_Size(o);
long total = 0;
if (n < 0)
{
return PyLong_FromLong(total);
}
PyObject* item;
for (int i = 0; i < n; i++)
{
item = PyList_GetItem(o, i);
if (!PyLong_Check(item)) continue;
total += PyLong_AsLong(item);
}
return PyLong_FromLong(total);
}
Run Code Online (Sandbox Code Playgroud)
基本上,这是文档页面上介绍中的功能。它应该接收一个python列表并返回所有元素的总和。如果我通过一个列表,该函数工作正常,如果我通过其他内容,但是出现错误消息
SystemError: c:\_work\5\s\objects\listobject.c:187: bad argument to internal function
Run Code Online (Sandbox Code Playgroud)
这种情况应该由if (n<0)语句处理,如果传递的对象不是列表,则n为-1。
我通过以下方式绑定功能:
static PyMethodDef example_module_methods[] = {
{ "sum_list", (PyCFunction)sum_elements, METH_O, nullptr},
{ nullptr, nullptr, 0, nullptr } …Run Code Online (Sandbox Code Playgroud) 这是我第一次为 python 编写 C 扩展,你可以看到我丑陋且可能超级低效的卷积 C++ 实现。我的内存管理有问题。每次我在 python 中调用这个函数时,它都会消耗大约 500MB 的内存(对于大小为 100x112x112x3 的批次和大小为 3x3x3x64 的内核),并且之后不会释放它。即使这不是类方法,我是否必须注意引用计数?或者我是否必须在代码中的某个位置手动释放内存?请注意,为了更好地概览,我排除了所有错误检查。谢谢。
PyObject* conv2d(PyObject*, PyObject* args)
{
PyObject* data;
PyObject* shape;
PyObject* kernel;
PyObject* k_shape;
int stride;
PyArg_ParseTuple(args, "OOOOi", &data, &shape, &kernel, &k_shape, &stride);
Py_ssize_t dims = PyTuple_Size(shape);
Py_ssize_t kernel_dims = PyTuple_Size(k_shape);
int shape_c[3];
int k_shape_c[4];
for (int i = 0; i < kernel_dims; i++)
{
if (i < dims)
{
shape_c[i] = PyLong_AsLong(PyTuple_GetItem(shape, i));
}
k_shape_c[i] = PyLong_AsLong(PyTuple_GetItem(k_shape, i));
}
PyObject* data_item, kernel_item;
PyObject* ret_array = …Run Code Online (Sandbox Code Playgroud)