首页 > 解决方案 > 解析参数时的 Python C API/ctypes 函数段错误

问题描述

我编写了一个 C++ 方法,它枚举给定邻接矩阵中指定大小的子图的数量。我正在尝试使此方法在 python 中可调用。基本方法签名接受一个列表和一个数字,并且(应该)返回一个子图列表,每个子图都由一个边列表表示。驱动方法如下所示:

// In python, this function will take two parameters
// arg1 - graph: An adjacency list
// arg2 - int: k, the subgraph size
extern "C" PyObject * enum_subgraphs(PyObject *self, PyObject *args)
{
  PyObject *graph;
  int k;
  if (!PyArg_ParseTuple(args, "Oi", &graph, &k)) return NULL;
  if (PyObject_Length(graph) < 0) return NULL;
  if (k <= 0) return NULL;

  // Hand the list to kavosh and initiialize connectivity list
  PyObject *connectivity = PyList_New(0);
  kavosh(graph, k, connectivity); // This is where all the real work is done
  return connectivity;
}

在同一文件中使用以下设置:

static PyMethodDef CISE[] = {
  { "cise", enum_subgraphs, METH_VARARGS, "Enumerates subgraphs of adjacency list" },
  { NULL, NULL, 0, NULL }
};

DL_EXPORT(void) initcise(void)
{
  Py_InitModule("cise", CISE);
}

然后在setup.py

from setuptools import setup, Extension
# Compile *cise_python.cpp* into a shared library
setup(
ext_modules=[Extension('cise', ['cise_python.cpp'],),],
)

在这一点上,一切似乎都可以编译并运行良好(但我将它们包括在内,以防我在他们的设置中出错)。但是,以下代码将始终失败:

from ctypes import *
import glob
libfile = glob.glob('build/*/cise*.so')[0]
c = CDLL(libfile)
c.enum_subgraphs.restype = py_object
c.enum_subgraphs.argtypes = [py_object, c_int]
graph = [[1, 2], [0, 2], [0, 1]]
c.enum_subgraphs(graph, 2)  # Segfault happens here

我的猜测是我所写内容的问题在于,argtypes但到目前为止我发现的一切都告诉我这很好。据我所知,分段错误是直接的,所以我不相信段错误是由我的实际方法实现引起的(与其他数据结构完美配合)。

任何可能导致我的程序崩溃的建议将不胜感激!

标签: pythonc++cctypespython-c-api

解决方案


使用此命令创建 Python C 扩展

 python setup.py build_ext --inplace

bind.c请正确设置您的

代码参考:bind.ca 和 PyMODINIT_FUNC 和 PyModuleDef


推荐阅读