【问题标题】:initializer is not a constant, error C2099, on compiling a module written in c for python初始化器不是常量,错误 C2099,在为 python 编译用 c 编写的模块时
【发布时间】:2017-07-30 16:13:18
【问题描述】:

我尝试在 Windows 10 上使用 msvc 2017 编译一个名为 distance 的 python 模块,其中 c "python setup.py install --with-c",但出现此错误,

Cdistance / distance.c (647): error C2099: initializer is not a 常数

Cdistance / distance.c (689): error C2099: initializer is not a 常数

错误:命令 'C:\Program Files (x86)\Microsoft Visual Studio\ 2017\BuildTools\VC\Tools\MSVC\14.10.25017\bin\HostX64\ x64 \ cl .exe '失败,退出状态为 2

这是第 647 行的代码

   646 PyTypeObject IFastComp_Type = {
   647     PyVarObject_HEAD_INIT(&PyType_Type, 0)
   648  "distance.ifast_comp", /* tp_name */
   649  sizeof(ItorState), /* tp_basicsize */
   650  0, /* tp_itemsize */
        (destructor)itor_dealloc, /* tp_dealloc */
        0, /* tp_print */
        0, /* tp_getattr */
        0, /* tp_setattr */
        0, /* tp_reserved */
        0, /* tp_repr */
        0, /* tp_as_number */
        0, /* tp_as_sequence */
        0, /* tp_as_mapping */
        0, /* tp_hash */
        0, /* tp_call */
        0, /* tp_str */
        0, /* tp_getattro */
        0, /* tp_setattro */
        0, /* tp_as_buffer */
        Py_TPFLAGS_DEFAULT, /* tp_flags */
        ifast_comp_doc, /* tp_doc */
        0, /* tp_traverse */
        0, /* tp_clear */
        0, /* tp_richcompare */
        0, /* tp_weaklistoffset */
        PyObject_SelfIter, /* tp_iter */
        (iternextfunc)ifastcomp_next, /* tp_iternext */
        0, /* tp_methods */
        0, /* tp_members */
        0, /* tp_getset */
        0, /* tp_base */
        0, /* tp_dict */
        0, /* tp_descr_get */
        0, /* tp_descr_set */
        0, /* tp_dictoffset */
        0, /* tp_init */
        PyType_GenericAlloc, /* tp_alloc */
        ifastcomp_new, /* tp_new */
    };

第689行是另一个类似结构,

688  PyTypeObject ILevenshtein_Type = {
689     PyVarObject_HEAD_INIT(&PyType_Type, 0)
        "distance.ilevenshtein", /* tp_name */
        sizeof(ItorState), /* tp_basicsize */
        0, /* tp_itemsize */
        (destructor)itor_dealloc, /* tp_dealloc */
        0, /* tp_print */
        0, /* tp_getattr */
        0, /* tp_setattr */
        0, /* tp_reserved */
        0, /* tp_repr */

两个引用如下,在同一个页面中

762 if (PyType_Ready(&IFastComp_Type) != 0 || PyType_Ready(&ILevenshtein_Type)!= 0)
763 #if PY_MAJOR_VERSION >= 3
        return NULL;
    #else
        return;
    #endif

    Py_INCREF((PyObject *)&IFastComp_Type);
    Py_INCREF((PyObject *)&ILevenshtein_Type);

谢谢

【问题讨论】:

  • 这一行“line 647”有很多行。哪个是 647,哪个是 689?
  • 你知道如何初始化全局变量吗?这些符号之一不是 const。发现哪一个,你就完成了。如果你不怎么 - 买一本好的 C 书,因为我们不是免费的学习服务
  • ifast_comp_doc 是如何以及在哪里声明的? (我只是将它与我​​们用 C++ 编写的 Python 类进行了比较。我看不出有什么明显的错误。)
  • 我按照 alk 的建议对其进行了编辑,是的,我当然用常量进行了编辑,但我不知道是哪一个,
  • @PeterJ: const 不会在 C 中创建常量。

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


【解决方案1】:

我找到了解决方案,通过查看结构 PyTypeObject PyTypeObject 的定义,我将 yVarObject_HEAD_INIT(&PyType_Type, 0) 更改为 PyVarObject_HEAD_INIT(NULL, 0) 并且它编译成功,我尝试了一些功能并且它有效,所以错误是由&PyType_Type 引起的,这是一个PyObject*,我知道因为IFastComp_Type 是一个全局变量,它应该由一个常量初始化,但我仍然不知道为什么模块的作者给&PyType_Type 作为争论,谢谢大家的cmets。

【讨论】:

    【解决方案2】:

    the documentation for "defining new types"

    PyVarObject_HEAD_INIT(NULL, 0)
    

    这条线有点儿毛病;我们想写的是:

    PyVarObject_HEAD_INIT(&PyType_Type, 0)

    因为类型对象的类型是“类型”,但这并不严格符合 C 语言并且一些编译器会抱怨。幸运的是,这个会员将由PyType_Ready()为我们填写。

    我认为 Visual C 是抱怨的编译器,并且该模块是使用 GCC 编写和测试的...

    【讨论】:

    • 我不确定一致性,我认为 VC 在这里的行为不正确
    • 很公平 - 我引用了 Python 文档,而不是声称了解 C 标准。在这里听起来好像 VC 是错误的,但是使用 Python C 接口的标准方法是编写 VC 可以应付的代码。
    • 在 Windows 上与 MinGW 的 gcc 有同样的问题。写作PyVarObject_HEAD_INIT(NULL, 0) 有帮助。
    猜你喜欢
    • 2011-09-02
    • 1970-01-01
    • 2011-09-02
    • 2011-05-26
    • 1970-01-01
    • 1970-01-01
    • 2020-08-14
    • 1970-01-01
    相关资源
    最近更新 更多