【问题标题】:Python C Api failing silentlyPython C Api 静默失败
【发布时间】:2019-12-31 19:39:26
【问题描述】:

我正在尝试为我的 C 应用程序创建一个 Python 接口,但是当我运行它时,shell 只是重置并且没有打印任何错误。这是我的代码:

#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>

如果有人知道如何获取错误消息或日志或可以指出问题的内容,并可能告诉我我做错了什么,那就太好了。

【问题讨论】:

  • 不确定 Windows 上的调试工具,但这种情况下的错误是您正在查找第 N 个参数而不是唯一参数的第 N 个元素
  • 问题是。您必须检查每个 C API 函数每个返回值,如果它们返回失败代码,您的函数必须以return NULL; 退出,这将导致Python端抛出异常,错误信息为描述.
  • 每一个真的意味着每一个,包括PyNumber_MultiplyPyTuple_GetItemPy_BuildValuePyTuple_NewPyTuple_SET_ITEM 不能失败,但你可以写越界。

标签: python c python-c-api


【解决方案1】:

问题是这个循环:

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);
}

通过调用PyTuple_GetItem(args, c),您将获取提供给您的函数的c'th 参数,但您只提供了一个参数。包含浮点数的元组。你可能打算这样做:

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);
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2019-07-22
    • 1970-01-01
    • 2021-03-25
    • 2021-10-04
    • 1970-01-01
    • 1970-01-01
    • 2017-01-10
    • 2018-09-30
    相关资源
    最近更新 更多