本文介绍了带有C的Python扩展:staticforward的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

So I needed to use the code of the subprocess module to add some functionality I needed. When I was trying to compile the _subprocess.c file, it gives this error message:

Error 1 error C2086: 'PyTypeObject sp_handle_type' : redefinition

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

This is the code part which is relevant from _subprocess.c file:

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编译此文件.

I don't understand what am I doing wrong. Any help would be appreciated.Btw (I'm not sure if it's relevant), I'm using Visual Studio Professional 2013 to compile this file.

推荐答案

注释:

  • 我在这里谈论的是 Python 2.7 (因为在新版本中, subprocess 模块不再为 Win )
  • Python 2.7 是根据VStudio2008(9.0)构建的(正式) rel ="nofollow noreferrer"> [Python.Wiki]:WindowsCompilers .使用较新的(或更好的:不同的)版本进行构建,可能会产生一些其他(更难找到)错误.例如,当我使用 VStudio 2010(10.0)构建它时(我使用构建的版本来运行一组复杂的( .py * )脚本),由于 errno 和 WSA * 代码之间的某些不匹配而在套接字版本错误中遇到运行时的麻烦,在两个版本之间进行了更改
  • I'm talking about Python 2.7 here (since in newer versions, the subprocess module no longer has an own C implementation for Win)
  • Python 2.7 is built (officially) using VStudio2008 (9.0) according to [Python.Wiki]: WindowsCompilers. Building it with a newer (or better: different) version, might yield some other (and harder to find) errors. For example, when I built it with VStudio 2010 (10.0) (I used the built version to run a complex set of (.py*) scripts), I had some trouble at runtime when encountering socket related errors because of some mismatches between errno and WSA* codes, that were changed between the 2 versions

当我进行测试时,我不明白您为什么遇到了这个问题,而我没有遇到这个问题,然后有一段时间我忘记了它,然后当您发布最后一条评论时,它又开始吞噬我.正如我所说,我能够使用 VStudio 2010/2013 成功编译文件.

When I tested, I couldn't understand why you encountered the issue and I didn't, then for a while I forgot about it, then when you posted the last comment, it started eating me alive again. As I said I was able to successfully compile the file using VStudio 2010 / 2013.

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

Trying to compile the same (this was only an assumption) code with different results -> the way that code is compiled might differ. Therefore, I started investigating for other possible definition places for staticforward and statichere (besides lines 878 / 879 of object.h) due to conditional macros: #if, #ifdef, ... . But, I couldn't find any. So, I added some simpler statements:

staticforward int i;
statichere int i = 2;

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

then, I manually replaced the defines:

static int i;
static int i = 2;

_subprocess.c 中的

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

in _subprocess.c (by coincidence, I added them at line #137 - just before statichere PyTypeObject sp_handle_type = { - fact that prevented me to figure out the problem at this point), and it still compiled!!!

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

Next step, I pasted the above lines in another solution that I had open (in a .cpp source file), and I was able to reproduce the error. So, I payed more attention to the compiler flags (I copy/pasted from the x86 Debug settings of the projects automatically converted by VStudio from the ones found in the PCbuild folder):

  • 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 C ++ ( [MS.Docs]:/Tc,/Tp,/TC,/TP(指定源文件类型)标志).当然,将 _subprocess.c 编译为 C ++ 会吐出错误.

    and then it struck me: It's the way of how the file is compiled: C vs. C++ (the [MS.Docs]: /Tc, /Tp, /TC, /TP (Specify Source File Type) flag). Of course, compiling _subprocess.c as C++ would spit your error.

    检查 [SO ]:使用2D动态分配的字符串(@CristiFati的答案)创建动态分配的结构,以获取更多细节,以及相同的错误如何引发截然不同的错误.

    Check [SO]: Creating a dynamically allocated struct with a 2D dynamically allocated string (@CristiFati's answer), for (a little bit) more details, and how the same mistake triggered very different errors.

    这篇关于带有C的Python扩展:staticforward的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

    09-05 10:44