2017-01-25 17 views
2

Поэтому мне нужно было использовать код модуля подпроцесса, чтобы добавить некоторые необходимые мне функции. Когда я пытался скомпилировать файл _subprocess.c, это дает сообщение об ошибке:Расширения Python с C: staticforward

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 

Я не понимаю, что я делаю неправильно. Любая помощь будет оценена по достоинству. Btw (я не уверен, что это актуально), я использую Visual Studio Professional 2013 для компиляции этого файла.

ответ

-1

Хорошо, я нашел ответ.

Оказалось, что определение staticforward должно быть extern вместо static. Мой компилятор не знал, как с этим справиться. Я думаю, что в других компиляторах он работает нормально.

+0

Этот файл (как и все остальные) должен скомпилировать _OOTB_. Я пробовал пару комбинаций (_VC2k10_ vs _Py27_ как, например,), но не смог воспроизвести проблему. Вы должны (искать дубликаты), и закрыть проблему. __Действительно, я не рассматриваю это как решение .__ – CristiFati

+0

В Visual Studio 2013 вы не можете определить статическую переменную дважды. staticforward и statichere были оба определены как «статические», поэтому на самом деле ошибка является законной. Изменение staticforward на 'extern' сообщает компилятору, что переменная будет определена позже. – Omer

+0

_ «В Visual Studio 2013 вы не можете определить статическую переменную дважды. Staticforward и statichere были defdeend как« static », поэтому на самом деле ошибка является допустимой». Это не может быть больше __wrong__. В любой версии компилятора _VStudio_ (или любой _VS_ или _C_) 'static' означает, что переменные видны только в модуле компиляции (_c_/_C++ _ file). Пожалуйста, ознакомьтесь с интернетом (_Google_, _MSDN_, _Wiki_, ... и тонны других). – CristiFati

0

Примечания:

  • Я говорю о PY27 здесь (так как в более новых версиях subprocess модуль больше не имеет собственного C реализацию Win).
  • Py27 построен (официально) с использованием VStudio 2008 (9.0) согласно [Python]: WindowsCompilers. Построение его с более новой (или лучше: другой) версией может привести к некоторым другим (и более трудным для поиска) ошибкам. Например, когда я построил его с VStudio 2010 (10.0) (я использовал встроенную версию для запуска сложного набора сценариев (.py *)), у меня были некоторые проблемы при времени исполнения при столкновении со связанными сокетами ошибками из-за некоторых несоответствий между кодами errno и WSA*, которые были изменены между двумя версиями.

Когда я протестировал, я не мог понять, почему вы столкнулись с проблемой, и я этого не сделал, но на некоторое время я забыл об этом, а затем, когда вы отправили последний комментарий, он снова начал меня оживать. Как я уже сказал, я смог успешно скомпилировать файл, используя VStudio 2k10 и 2k13.

Пытается скомпилировать эти же (это был только предположение) код с различными результатами ->способ этот код скомпилирован может отличаться. Поэтому я начал исследовать другие возможные места для определения staticforward и statichere (кроме линий/из object.h) из-за условные макросы: #if, #ifdef .... Но я не мог найти.Таким образом, я добавил некоторые простые утверждения:

staticforward int i; 
statichere int i = 2; 

тогда, я вручную заменил устанавливает:

static int i; 
static int i = 2; 

в _subprocess.c (по совпадению, я добавил их в строке - просто до statichere PyTypeObject sp_handle_type = { - факт, который помешал мне разобраться с проблемой на данный момент), и он все еще скомпилирован !!!

Следующий шаг, я вставил вышеуказанные строки в другое решение, которое у меня было открыто (в исходном файле .cpp), и я смог воспроизвести ошибку. Таким образом, я заплатил больше внимания на флаги компилятора (копировать/вставить из x86Debug настройки проектов автоматически преобразованы VStudio из тех, найденных в PCbuild папку):

  • VStudio2k13

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

    /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++ ([MSDN]: /Tc, /Tp, /TC, /TP (Specify Source File Type) флаг). Конечно, компиляция _subprocess.c как C++ выплюнул бы вашу ошибку.

Проверьте мой ответ на [SO]: Creating a dynamically allocated struct with a 2D dynamically allocated string, для (немного) более подробной информации и о том, как одна и та же ошибка вызвала очень разные ошибки.

+0

Отвечает ли это на ваш вопрос? – CristiFati