0

I wrote a c++ module witch should be imported into Python. Below are both Codes, the C++ part and the Python part. The C++ function method_sum should return the double of a value to python.

module.cpp:

#define PY_SSIZE_T_CLEAN
#include <Python.h>

static PyObject *method_sum(PyObject *self, PyObject *args) {
  const int *prop;

  if (!PyArg_ParseTuple(args, "i", &prop)) return NULL;

  int result = *prop + *prop;
  return Py_BuildValue("i", result);
}

static PyMethodDef ModuleMethods[] = {
    {"sum", method_sum, METH_VARARGS, "description of the function"},
    {NULL, NULL, 0, NULL}
};

static struct PyModuleDef module = {
    PyModuleDef_HEAD_INIT,
    "module",
    "description of the module",
    -1,
    ModuleMethods
};

PyMODINIT_FUNC PyInit_module(void) {
    return PyModule_Create(&module);
}

main.py:

import module

print(module.sum(18))

setup.py:

from distutils.core import setup, Extension

setup(name='module', version='1.0', ext_modules=[Extension('module', ['module.cpp'])])
Tillmann
  • 61
  • 1
  • 5
  • 1
    Please supply the expected [minimal, reproducible example](https://stackoverflow.com/help/minimal-reproducible-example) (MRE). We should be able to copy and paste a contiguous block of your code, execute that file, and reproduce your problem along with tracing output for the problem points. This lets us test our suggestions against your test data and desired output. This includes a driver to provoke the error, trace data, and the full error message. – Prune May 26 '21 at 22:17

1 Answers1

2

I changed method_sum to the following and main.py prints 36 instead of segfaulting.

static PyObject *method_sum(PyObject *self, PyObject *args) {
  int prop;

  if (!PyArg_ParseTuple(args, "i", &prop)) return NULL;

  int result = prop + prop;
  return Py_BuildValue("i", result);
}

The following also works and prop is still a pointer like in the code in the question.

static PyObject *method_sum(PyObject *self, PyObject *args) {
  const int *prop = new int;

  if (!PyArg_ParseTuple(args, "i", prop)) {
    delete prop;
    return NULL;
  }

  int result = *prop + *prop;
  delete prop;
  return Py_BuildValue("i", result);
}
Nathan Mills
  • 2,243
  • 2
  • 9
  • 15
  • OP was attempting to parse the `int` as a `const int*`, most likely due to incorrectly modifying the ubiquitous `spam.system("ls -la")` example argument which was a `const char*` (a C string) . If they did want to pass an `int *` however, they should use `"O"` instead of `"i"`, to parse as an arbitrary object. – jackw11111 May 27 '21 at 00:03