【问题标题】:Python extensions with C: staticforward使用 C 的 Python 扩展:staticforward
【发布时间】:2017-06-11 05:59:21
【问题描述】:

所以我需要使用子流程模块的代码来添加一些我需要的功能。当我试图编译 _subprocess.c 文件时,它给出了以下错误消息:

Error 1 error C2086: 'PyTypeObject sp_handle_type' : redefinition

这是与_subprocess.c 文件相关的代码部分:

typedef struct {
    PyObject_HEAD
    HANDLE handle;
} sp_handle_object;

staticforward PyTypeObject sp_handle_type;

static PyObject*
sp_handle_new(HANDLE handle)
{
    sp_handle_object* self;

    self = PyObject_NEW(sp_handle_object, &sp_handle_type);
    if (self == NULL)
        return NULL;

    self->handle = handle;

    return (PyObject*)self;
}

#if defined(MS_WIN32) && !defined(MS_WIN64)
#define HANDLE_TO_PYNUM(handle) PyInt_FromLong((long) handle)
#define PY_HANDLE_PARAM "l"
#else
#define HANDLE_TO_PYNUM(handle) PyLong_FromLongLong((long long) handle)
#define PY_HANDLE_PARAM "L"
#endif

static PyObject*
sp_handle_detach(sp_handle_object* self, PyObject* args)
{
    HANDLE handle;

    if (!PyArg_ParseTuple(args, ":Detach"))
        return NULL;

    handle = self->handle;

    self->handle = INVALID_HANDLE_VALUE;

    /* note: return the current handle, as an integer */
    return HANDLE_TO_PYNUM(handle);
}

static PyObject*
sp_handle_close(sp_handle_object* self, PyObject* args)
{
    if (!PyArg_ParseTuple(args, ":Close"))
        return NULL;

    if (self->handle != INVALID_HANDLE_VALUE) {
        CloseHandle(self->handle);
        self->handle = INVALID_HANDLE_VALUE;
    }
    Py_INCREF(Py_None);
    return Py_None;
}

static void
sp_handle_dealloc(sp_handle_object* self)
{
    if (self->handle != INVALID_HANDLE_VALUE)
        CloseHandle(self->handle);
    PyObject_FREE(self);
}

static PyMethodDef sp_handle_methods[] = {
    { "Detach", (PyCFunction)sp_handle_detach, METH_VARARGS },
    { "Close", (PyCFunction)sp_handle_close, METH_VARARGS },
    { NULL, NULL }
};

static PyObject*
sp_handle_getattr(sp_handle_object* self, char* name)
{
    return Py_FindMethod(sp_handle_methods, (PyObject*)self, name);
}

static PyObject*
sp_handle_as_int(sp_handle_object* self)
{
    return HANDLE_TO_PYNUM(self->handle);
}

static PyNumberMethods sp_handle_as_number;

statichere PyTypeObject sp_handle_type = {
    PyObject_HEAD_INIT(NULL)
    0,                                  /*ob_size*/
    "_subprocess_handle", sizeof(sp_handle_object), 0,
    (destructor)sp_handle_dealloc, /*tp_dealloc*/
    0, /*tp_print*/
    (getattrfunc)sp_handle_getattr,/*tp_getattr*/
    0,                                  /*tp_setattr*/
    0,                                  /*tp_compare*/
    0,                                  /*tp_repr*/
    &sp_handle_as_number,               /*tp_as_number */
    0,                                  /*tp_as_sequence */
    0,                                  /*tp_as_mapping */
    0                                   /*tp_hash*/
};`

我还发现:

#define staticforward static
#define statichere static

我不明白我做错了什么。任何帮助,将不胜感激。 顺便说一句(我不确定它是否相关),我正在使用 Visual Studio Professional 2013 来编译这个文件。

【问题讨论】:

    标签: python c forward-declaration python-extensions


    【解决方案1】:

    注意事项

    • 我在这里谈论的是 Python 2.7(因为在较新的版本中,subprocess 模块不再有自己的 C 实现em>赢)
    • Python 2.7 根据[Python.Wiki]: WindowsCompilers 使用VStudio2008 (9.0) 构建(官方)。使用更新的(或更好的:不同的)版本构建它,可能会产生一些其他(更难找到)错误。例如,当我使用 VStudio 2010 (10.0) 构建它时(我使用构建的版本来运行一组复杂的 (.py*) 脚本),我有一些由于 errnoWSA* 代码之间的一些不匹配,在遇到与套接字相关的错误时在 runtime 出现问题,这两个版本之间已更改

    当我测试的时候,我不明白你为什么遇到这个问题而我没有,然后有一段时间我忘记了它,然后当你发布最后一条评论时,它又开始把我活生生地吃掉了。正如我所说,我能够使用 VStudio 2010 / 2013 成功编译该文件。

    尝试以不同的结果编译相同(这只是一个假设)代码 -> 编译代码的方式可能会有所不同。因此,我开始研究 staticforwardstatichere 的其他可能定义位置(除了 878 / 879 行em>object.h)由于条件宏:#if#ifdef、. ...但是,我找不到任何东西。所以,我添加了一些更简单的语句:

    staticforward int i;
    statichere int i = 2;
    

    然后,我手动替换了定义:

    static int i;
    static int i = 2;
    

    _subprocess.c 中(巧合的是,我在 #137 行添加了它们 - 就在 statichere PyTypeObject sp_handle_type = { 之前 - 这让我无法找出问题所在点),它仍然编译!!!

    下一步,我将上述行粘贴到我打开的另一个解决方案中(在 .cpp 源文件中),我能够重现该错误。因此,我更加关注编译器标志(我从 VStudio 自动转换的项目的 x86 调试 设置中复制/粘贴了 PCbuild 文件夹):

    • VStudio 2013

      /GS
      /analyze-
      /W3
      /Gy
      /Zc:wchar_t
      /I"E:\Work\Dev\Fati\WinBuild\OPSWpython27\src\Python-2.7.11-vs2k13\Python"
      /I"E:\Work\Dev\Fati\WinBuild\OPSWpython27\src\Python-2.7.11-vs2k13\Modules\zlib"
      /I"E:\Work\Dev\Fati\WinBuild\OPSWpython27\src\Python-2.7.11-vs2k13\Include"
      /I"E:\Work\Dev\Fati\WinBuild\OPSWpython27\src\Python-2.7.11-vs2k13\PC"
      /Zi
      /Gm-
      /Od
      /Fd"E:\Work\Dev\Fati\WinBuild\OPSWpython27\src\Python-2.7.11-vs2k13\PCbuild\obj\win32_Debug\pythoncore\vc120.pdb"
      /fp:precise
      /D "_USRDLL"
      /D "Py_BUILD_CORE"
      /D "Py_ENABLE_SHARED"
      /D "MS_DLL_ID=\"2.7-32\""
      /D "WIN32"
      /D "_WIN32"
      /D "_DEBUG"
      /D "_WINDLL"
      /errorReport:prompt
      /GF
      /WX-
      /Zc:forScope
      /Gd
      /Oy-
      /Oi
      /MDd
      /Fa"E:\Work\Dev\Fati\WinBuild\OPSWpython27\src\Python-2.7.11-vs2k13\PCbuild\obj\win32_Debug\pythoncore\"
      /nologo
      /Fo"E:\Work\Dev\Fati\WinBuild\OPSWpython27\src\Python-2.7.11-vs2k13\PCbuild\obj\win32_Debug\pythoncore\"
      /Fp"E:\Work\Dev\Fati\WinBuild\OPSWpython27\src\Python-2.7.11-vs2k13\PCbuild\obj\win32_Debug\pythoncore\python27_d.pch"
      
    • VStudio 2010

      /I"..\Python"
      /I"..\Modules\zlib"
      /I"..\Include"
      /I"..\PC"
      /Zi
      /nologo
      /W3
      /WX-
      /Od
      /Oy-
      /D "_USRDLL"
      /D "Py_BUILD_CORE"
      /D "Py_ENABLE_SHARED"
      /D "WIN32"
      /D "_DEBUG"
      /D "_WIN32"
      /D "_WINDLL"
      /GF
      /Gm-
      /MDd
      /GS
      /Gy
      /fp:precise
      /Zc:wchar_t
      /Zc:forScope
      /Fp"E:\Work\Dev\Fati\WinBuild\OPSWpython27\src\Python-2.7.10-vcbuild\PCbuild\Win32-temp-Debug\pythoncore\pythoncore.pch"
      /Fa"E:\Work\Dev\Fati\WinBuild\OPSWpython27\src\Python-2.7.10-vcbuild\PCbuild\Win32-temp-Debug\pythoncore\"
      /Fo"E:\Work\Dev\Fati\WinBuild\OPSWpython27\src\Python-2.7.10-vcbuild\PCbuild\Win32-temp-Debug\pythoncore\"
      /Fd"E:\Work\Dev\Fati\WinBuild\OPSWpython27\src\Python-2.7.10-vcbuild\PCbuild\Win32-temp-Debug\pythoncore\vc100.pdb"
      /Gd
      /analyze-
      /errorReport:queue
      

    然后让我印象深刻:这是文件的编译方式:C vs. C++[MS.Docs]: /Tc, /Tp, /TC, /TP (Specify Source File Type) 标志)。当然,将 _subprocess.c 编译为 C++ 会报错。

    查看[SO]: Creating a dynamically allocated struct with a 2D dynamically allocated string (@CristiFati's answer),了解(一点点)更多详细信息,以及同一个错误如何引发截然不同的错误。

    【讨论】:

    • 这是否可以作为您问题的答案?
    【解决方案2】:

    好的,我找到了答案。

    原来staticforward 的定义应该是extern 而不是static。我的编译器不知道如何处理它。我猜在其他编译器中它工作正常。

    【讨论】:

    • 这个文件(和所有其他文件一样)应该编译,OOTB。我尝试了几种组合(例如 VC2k10 vs Py27),但无法重现该问题。您可能应该(寻找重复)并关闭问题。 无论如何,我不认为这是一个解决方案。
    • 在 Visual Studio 2013 中,不能两次定义静态变量。 staticforward 和 statichere 都被定义为“静态”,所以事实上,这个错误是合法的。将 staticforward 更改为 extern 告诉编译器该变量将在稍后定义。
    • "在 Visual Studio 2013 中,你不能定义一个静态变量两次。staticforward 和 statichere 都被定义为 'static' 所以实际上错误是合法的" .这简直是​​错误。在任何 VStudio(或任何 VSC)编译器版本中,static 表示变量仅在编译单元中可见( c / c++ 文件)。有关详细信息,请查看互联网(GoogleMSDNWiki 等)。
    • 整个社区都犯了这样的错误(命名staticforward(staic) 但意思是extern)和2017年 是找到它的人。顺便说一句,在我的盒子上,Py2.7.10 编译 OOTB 使用 VS2k13....现在,问题是:你对 subprocess.c(或包含的标题之一)把事情搞得这么糟糕?
    • 你真正想做什么?
    猜你喜欢
    • 1970-01-01
    • 2010-11-07
    • 2012-01-05
    • 1970-01-01
    • 1970-01-01
    • 2011-03-31
    • 1970-01-01
    • 2017-12-16
    • 1970-01-01
    相关资源
    最近更新 更多