-1

I'm trying to make a Python interface for my C-application, but when I run it the shell just resets and no error is printed. Here is my code:

#include <Python.h>

#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>

static PyObject *method_doubletuple(self, args)
    PyObject *self;
    PyObject *args;
{
    PyObject *ret = PyTuple_New(16);
    for (int c = 0; c < 16; c++) {
        PyObject *newValue = PyNumber_Multiply(PyTuple_GetItem(args, c), Py_BuildValue("%u", (int)2));
        PyTuple_SET_ITEM(ret, c, newValue);
    }
    return ret;
}

static PyMethodDef PyTestMethods[] = {
    {"system", method_doubletuple, METH_VARARGS, "Doubles the value of a tuple with 16 elements"},
    {NULL, NULL, 0, NULL}
};

static struct PyModuleDef pytestmodule = {
    PyModuleDef_HEAD_INIT,
    "pytest",
    "pytest",
    -1,
    PyTestMethods
};

PyMODINIT_FUNC PyInit_pytest(void) {
    return PyModule_Create(&pytestmodule);
}
C:\Users\jotje\Desktop\Chess\SampleCModule>python setup.py install
running install
running build
running build_ext
building 'pytest' extension
C:\Program Files (x86)\Microsoft Visual Studio\2017\Community\VC\Tools\MSVC\14.16.27023\bin\HostX86\x64\cl.exe /c /nologo /Ox /W3 /GL /DNDEBUG /MD -IC:\Users\jotje\AppData\Local\Programs\Python\Python36\include -IC:\Users\jotje\AppData\Local\Programs\Python\Python36\include "-IC:\Program Files (x86)\Microsoft Visual Studio\2017\Community\VC\Tools\MSVC\14.16.27023\include" "-IC:\Program Files (x86)\Windows Kits\10\include\10.0.16299.0\ucrt" "-IC:\Program Files (x86)\Windows Kits\10\include\10.0.16299.0\shared" "-IC:\Program Files (x86)\Windows Kits\10\include\10.0.16299.0\um" "-IC:\Program Files (x86)\Windows Kits\10\include\10.0.16299.0\winrt" "-IC:\Program Files (x86)\Windows Kits\10\include\10.0.16299.0\cppwinrt" /Tcaddarray.c /Fobuild\temp.win-amd64-3.6\Release\addarray.obj
addarray.c
addarray.c(20): warning C4113: 'PyObject *(__cdecl *)()' differs in parameter lists from 'PyCFunction'
C:\Program Files (x86)\Microsoft Visual Studio\2017\Community\VC\Tools\MSVC\14.16.27023\bin\HostX86\x64\link.exe /nologo /INCREMENTAL:NO /LTCG /DLL /MANIFEST:EMBED,ID=2 /MANIFESTUAC:NO /LIBPATH:C:\Users\jotje\AppData\Local\Programs\Python\Python36\libs /LIBPATH:C:\Users\jotje\AppData\Local\Programs\Python\Python36\PCbuild\amd64 "/LIBPATH:C:\Program Files (x86)\Microsoft Visual Studio\2017\Community\VC\Tools\MSVC\14.16.27023\lib\x64" "/LIBPATH:C:\Program Files (x86)\Windows Kits\10\lib\10.0.16299.0\ucrt\x64" "/LIBPATH:C:\Program Files (x86)\Windows Kits\10\lib\10.0.16299.0\um\x64" /EXPORT:PyInit_pytest build\temp.win-amd64-3.6\Release\addarray.obj /OUT:build\lib.win-amd64-3.6\pytest.cp36-win_amd64.pyd /IMPLIB:build\temp.win-amd64-3.6\Release\pytest.cp36-win_amd64.lib
   Creating library build\temp.win-amd64-3.6\Release\pytest.cp36-win_amd64.lib and object build\temp.win-amd64-3.6\Release\pytest.cp36-win_amd64.exp
Generating code
Finished generating code
running install_lib
copying build\lib.win-amd64-3.6\pytest.cp36-win_amd64.pyd -> C:\Users\jotje\AppData\Local\Programs\Python\Python36\Lib\site-packages
running install_egg_info
Removing C:\Users\jotje\AppData\Local\Programs\Python\Python36\Lib\site-packages\pytest-1.0.0-py3.6.egg-info
Writing C:\Users\jotje\AppData\Local\Programs\Python\Python36\Lib\site-packages\pytest-1.0.0-py3.6.egg-info

C:\Users\jotje\Desktop\Chess\SampleCModule>python
Python 3.6.6 (v3.6.6:4cf1f54eb7, Jun 27 2018, 03:37:03) [MSC v.1900 64 bit (AMD64)] on win32
Type "help", "copyright", "credits" or "license" for more information.
>>> import pytest
>>> pytest.doubletuple((4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4))

C:\Users\jotje\Desktop\Chess\SampleCModule>

If anyone knows how to get an error message or logs or something which would point out the problem, and maybe tell me what I'm doing wrong that would be great.

S.S. Anne
  • 15,171
  • 8
  • 38
  • 76
jotjern
  • 460
  • 5
  • 18
  • 2
    not sure about the debugging tools on windows, but the bug in this case is you're looking up the Nth argument instead of the Nth element of the only argument – anthony sottile Dec 31 '19 at 21:22
  • 1
    The problem is **you**. You must check **each and every single return value** of **every C API function** and if they return a failure code, **your function must exit with `return NULL;` which will cause an exception be thrown in the Python side, with the error message as the description**. – Antti Haapala -- Слава Україні Jan 01 '20 at 10:06
  • And that every really means every, including `PyNumber_Multiply`, `PyTuple_GetItem`, `Py_BuildValue` and `PyTuple_New`. The `PyTuple_SET_ITEM` can't fail, but you can write out of bounds. – Antti Haapala -- Слава Україні Jan 01 '20 at 10:09

1 Answers1

-1

The problem is this loop:

for (int c = 0; c < 16; c++) {
    PyObject *newValue = PyNumber_Multiply(PyTuple_GetItem(args, c), Py_BuildValue("%u", (int)2));
    PyTuple_SET_ITEM(ret, c, newValue);
}

By calling PyTuple_GetItem(args, c) you're taking the c'th argument provided to your function, but you only provide a single argument. The tuple containing the floats. You probably meant to do something like this:

PyObject *input = PyTuple_GetItem(args, 0); 
for (int c = 0; c < 16; c++) {
    PyObject *newValue = PyNumber_Multiply(PyTuple_GetItem(input, c), Py_BuildValue("%u", (int)2));
    PyTuple_SET_ITEM(ret, c, newValue);
}
nickelpro
  • 2,537
  • 1
  • 19
  • 25