【问题标题】:Taking arguments辩论
【发布时间】:2018-12-02 03:10:11
【问题描述】:

我正在尝试创建一个需要争论的 Python 扩展。这是我的脚本:

#include <Python.h>

static PyObject * _message(PyObject *self, PyObject *args) {
    char *title, *message;

    if (!PyArg_ParseTuple(args, &title, &message)) 
        return NULL; // Throw an error

    return Py_BuildValue("");
}


static PyMethodDef methods[] = {
    {"Message", (PyCFunction) _message, METH_VARARGS, "Message(title, message) Take a message"},
    {NULL, NULL, 0, NULL} 
};


static struct PyModuleDef functions = {
    PyModuleDef_HEAD_INIT,
    "test", 
    "Take a message", 
    "-1",
    methods 

};

PyMODINIT_FUNC PyInit_test(void) {

    PyObject *module = PyModule_Create(&functions);

    return module;
}

Setup.py:

from setuptools import setup, Extension

module = Extension (
    "test",
    sources = ['test.c'])


setup(
    name = "test",
    version = "1.0",
    description = "Take message input",
    author = "Simon",
    ext_modules = [module])

但是,当我尝试编译它时,出现了一个错误:

C:\Users\Simon\Desktop\PyTest>python setup.py build
running build
running build_ext
building 'test' extension
C:\Program Files (x86)\Microsoft Visual Studio\2017\WDExpress\VC\Tools\MSVC\14.14.26428\bin\HostX86\x86\cl.exe /c /nologo /Ox /W3 /GL /DNDEBUG /MT -IC:\Users\Simon\AppData\Local\Programs\Python\Python36-32\include -IC:\Users\Simon\AppData\Local\Programs\Python\Python36-32\include "-IC:\Program Files (x86)\Microsoft Visual Studio\2017\WDExpress\VC\Tools\MSVC\14.14.26428\include" "-IC:\Program Files (x86)\Windows Kits\NETFXSDK\4.6.1\include\um" "-IC:\Program Files (x86)\Windows Kits\10\include\10.0.17134.0\ucrt" "-IC:\Program Files (x86)\Windows Kits\10\include\10.0.17134.0\shared" "-IC:\Program Files (x86)\Windows Kits\10\include\10.0.17134.0\um" "-IC:\Program Files (x86)\Windows Kits\10\include\10.0.17134.0\winrt" "-IC:\Program Files (x86)\Windows Kits\10\include\10.0.17134.0\cppwinrt" /Tctest.c /Fobuild\temp.win32-3.6\Release\test.obj
test.c
test.c(2): warning C4067: unexpected tokens following preprocessor directive - expected a newline
test.c(10): warning C4047: 'function': 'const char *' differs in levels of indirection from 'char **'
test.c(10): warning C4024: 'PyArg_ParseTuple': different types for formal and actual parameter 2
test.c(23): warning C4047: 'initializing': 'Py_ssize_t' differs in levels of indirection from 'char [3]'
test.c(42): warning C4047: 'function': 'const char *' differs in levels of indirection from 'int'
test.c(42): warning C4024: 'PyModule_AddStringConstant': different types for formal and actual parameter 3
C:\Program Files (x86)\Microsoft Visual Studio\2017\WDExpress\VC\Tools\MSVC\14.14.26428\bin\HostX86\x86\link.exe /nologo /INCREMENTAL:NO /LTCG /nodefaultlib:libucrt.lib ucrt.lib /DLL /MANIFEST:EMBED,ID=2 /MANIFESTUAC:NO /LIBPATH:C:\Users\Simon\AppData\Local\Programs\Python\Python36-32\libs /LIBPATH:C:\Users\Simon\AppData\Local\Programs\Python\Python36-32\PCbuild\win32 "/LIBPATH:C:\Program Files (x86)\Microsoft Visual Studio\2017\WDExpress\VC\Tools\MSVC\14.14.26428\lib\x86" "/LIBPATH:C:\Program Files (x86)\Windows Kits\NETFXSDK\4.6.1\lib\um\x86" "/LIBPATH:C:\Program Files (x86)\Windows Kits\10\lib\10.0.17134.0\ucrt\x86" "/LIBPATH:C:\Program Files (x86)\Windows Kits\10\lib\10.0.17134.0\um\x86" test.lib /EXPORT:PyInit_test build\temp.win32-3.6\Release\test.obj /OUT:build\lib.win32-3.6\test.cp36-win32.pyd /IMPLIB:build\temp.win32-3.6\Release\test.cp36-win32.lib
   Creating library build\temp.win32-3.6\Release\test.cp36-win32.lib and object build\temp.win32-3.6\Release\iup.cp36-win32.exp
Generating code
Finished generating code

我很确定我的其余代码都是正确的,除了在以下位置使用参数:

static PyObject * _message(PyObject *self, PyObject *args) {
    char *title, *message;

    if (!PyArg_ParseTuple(args, &title, &message)) 

扩展程序已创建,但是当我尝试运行它时,它崩溃了。

如何获取位置参数?

【问题讨论】:

  • 错误消息似乎很有启发性。检查他们提到的具体内容的文档,例如 PyArg_ParseTuple。
  • 您需要在第二个参数中指定参数的类型。例如:if (!PyArg_ParseTuple(args,"zz",&amp;title, &amp;message)),其中z 表示 C 风格的零分隔字符串,"zz" 表示你有两个。
  • @cdarke 是的,我已经阅读过,我没有意识到我需要在该论点中包含一个(但这是有道理的)。谢谢。
  • 我错过了,你的`“-1”,`应该是-1 in functions
  • 我很高兴你能成功。我已经写了一个答案。

标签: python c function arguments python-c-api


【解决方案1】:

你在寻找 disutils 吗?

这个库可以运行 C 代码,也许可以帮助你。您可以在 Python 官方文档的此页面中获取更多信息:https://docs.python.org/3/extending/building.html

【讨论】:

  • 感谢您的回答,但我认为您的方法有误。 setuptools 推荐阅读this answer
  • 在您的屏幕截图上,您的编译器告诉您他遇到了未知令牌。这是一个错误,我仍然认为这是因为您试图将 C 文件解析为 Python 文件,但脚本仍在运行并生成可执行文件它崩溃了,因为它可能因解析失败而损坏。在 Python v3.5.4 的文档中有一个 C 语言导入的示例,我认为你应该看看它。
  • 这不是我的反对意见,这里有相同的英文文档:docs.python.org/3/extending/building.html 如果你想编辑它。我会读的。谢谢。
  • 感谢您的好意,我编辑了我的帖子,因为我意识到我的方式不适合您,我的错误!
【解决方案2】:

您需要在第二个参数中指定参数的类型。例如:

if (!PyArg_ParseTuple(args,"zz", &title, &message))

其中z 表示C 风格的零分隔字符串,"zz" 表示您有两个。这些被称为specifers,其中有很多,这里有一些最常见的:

i/I     Signed/unsigned int
d/D     Signed/unsigned double
s       C-style string (char *)
z       C-style string or None
y       bytes object
O       Generic Python object (oh)
O!      Typed Python object (oh!)

另外,你的"-1" 应该是-1 in functions

【讨论】:

    猜你喜欢
    • 2011-02-22
    • 1970-01-01
    • 1970-01-01
    • 2016-02-15
    • 1970-01-01
    • 1970-01-01
    • 2010-12-26
    • 1970-01-01
    • 2013-07-10
    相关资源
    最近更新 更多