简体   繁体   English

使用C:staticforward的Python扩展

[英]Python extensions with C: staticforward

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: 当我尝试编译_subprocess.c文件时,它给出以下错误消息:

Error 1 error C2086: 'PyTypeObject sp_handle_type' : redefinition

This is the code part which is relevant from _subprocess.c file: 这是与_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*/
};`

Also I've found that: 我也发现:

#define staticforward static
#define statichere static

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. 顺便说一句(我不确定是否相关),我正在使用Visual Studio Professional 2013编译此文件。

Notes : 注意事项

  • 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 (因为在新版本中, 进程模块不再具有Win的自己的C实现)
  • Python 2.7 is built (officially) using VStudio2008 (9.0) according to [Python.Wiki]: WindowsCompilers . 根据[Python.Wiki]:WindowsCompilers,使用VStudio2008(9.0)构建(正式) Python 2.7 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(10.0)构建它时(我使用构建的版本来运行一组复杂的( .py * )脚本),由于errno之间的某些不匹配,在运行时遇到与套接字相关的错误时会遇到一些麻烦和WSA *代码,在两个版本之间进行了更改

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 . 如我所说,我能够使用VStudio 2010/2013成功编译文件。

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 , ... . 因此,我开始调查在staticforwardstatichere其他可能的定义的地方(除了线object.h879分之878)由于条件的宏:#如果 ,#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;

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!!! _subprocess.c中 (巧合的是,我在第137行处添加了它们-就在statichere PyTypeObject sp_handle_type = { -实际上这使我无法找出问题),并且仍在编译!!

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. 下一步,我将上述行粘贴到了我打开的另一个解决方案中(在.cpp源文件中),并且能够重现该错误。 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): 因此,我更加注意了编译器标志(我从VStudioPCbuild文件夹中找到的项目的x86调试设置中复制/粘贴):

  • VStudio 2013 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 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 

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). 然后让我震惊的是:文件的编译方式是: C vs. C ++[MS.Docs]:/ Tc,/ Tp,/ TC,/ TP(指定源文件类型)标志)。 Of course, compiling _subprocess.c as C++ would spit your error. 当然,将_subprocess.c编译为C ++会吐出您的错误。

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

Ok I found an answer. 好吧,我找到了答案。

It turns out that the definition of staticforward should have been extern instead of static . 事实证明, staticforward的定义应该是extern而不是static My compiler didn't know how to handle it. 我的编译器不知道如何处理。 I guess in other compilers it works ok. 我猜在其他编译器中也可以。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM