【问题标题】:Python C API/ctypes function segfaults when parsing arguments解析参数时的 Python C API/ctypes 函数段错误
【发布时间】:2020-07-16 07:25:45
【问题描述】:

我编写了一个 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,但到目前为止我发现的一切都告诉我这很好。据我所知,分段错误是即时的,所以我不相信段错误是由我的实际方法实现引起的(与其他数据结构完美配合)。

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

【问题讨论】:

  • 第一步,将CDLL替换为PyDLL。不能在 CDLL 中调用 Python C API 函数。
  • 实际上,您似乎正在尝试编写扩展模块。您需要将其作为模块导入,而不是与 ctypes 混淆。
  • PyDLL 仍会导致段错误。如何将我的代码作为模块导入?关于这个主题有什么好的指南吗?我不知道有什么区别。
  • 使用import,与任何其他模块相同。 (导入系统确实需要能够找到它,就像任何其他模块一样。)
  • 啊,是的,那是票!一旦我设法正确设置了我的模块,它就可以完美运行!谢谢

标签: python c++ c ctypes python-c-api


【解决方案1】:

使用此命令创建 Python C 扩展

 python setup.py build_ext --inplace

请正确设置您的bind.c

代码参考:bind.c a and PyMODINIT_FUNC and PyModuleDef

【讨论】:

    猜你喜欢
    • 2011-07-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-05-15
    • 1970-01-01
    • 2021-07-12
    相关资源
    最近更新 更多