C:staticforward的Python扩展

所以我需要使用子进程模块的代码来添加我需要的一些function。 当我尝试编译_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来编译这个文件。

备注

  • 我在这里谈论Python2.7 (因为在较新的版本中, subprocess进程模块不再拥有Win的自己的C实现)
  • 根据[Python]:WindowsCompilers,使用VStudio2008(9.0)构建(正式) Python2.7 。 使用更新(或更好:不同)版本构建它可能会产生一些其他(并且更难找到)错误。 例如,当我使用VStudio2010(10.0)构建它时(我使用内置版本运行一组复杂的( .py * )脚本),遇到套接字相关错误时,由于errnoerrno之间的一些不匹配,我在运行时遇到了一些麻烦。 WSA*代码,在两个版本之间进行了更改

当我测试时,我无法理解为什么你遇到了这个问题而我没有,然后有一段时间我忘了它,然后当你发布最后一条评论时,它又开始让我活着。 正如我所说,我能够使用VStudio20102013成功编译文件。

尝试编译具有不同结果的相同(这只是一个假设)代码 – >编译代码的方式可能不同。 因此,我开始研究staticforwardstatichere其他可能的定义位置(除了object.h的第 statichere行),因为条件宏: #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源文件中),我能够重现错误。 所以,我更加注意编译器标志(我从PCbuild文件夹中找到的VStudio自动转换的项目的x86 Debug设置中复制/粘贴):

  • VStudio2013

     /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" 
  • VStudio2010

     /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 

然后它让我印象深刻:这是文件编译方式: CC ++ ( [MSDN]:/ Tc,/ Tp,/ TC,/ TP(指定源文件类型)标志)。 当然,将_subprocess.c编译为C ++会吐出错误。

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

好的,我找到了答案。

事实certificate, staticforward的定义应该是extern而不是static 。 我的编译器不知道如何处理它。 我想在其他编译器中它可以正常工作。