Python C API:使用 MSVC 尝试示例模块时出现访问冲突
Python C API: Access Violation when trying example module with MSVC
我正在用 C++ 制作一个 Python 模块。到目前为止,我使用 MingW 编译模块,效果很好。但我想切换到 MSVC,因为我使用的其他库更易于与 MSVC 一起使用。
但是,我无法让它工作。编译和链接工作正常,但是当我尝试使用来自 Python 的新创建模块时出现问题。我在调用 PyType_Ready
时收到错误 SystemError: Type does not define the tp_name field.
。在Python的源码里看到tp_name
为null的时候报这个错,但是我查了一下不为null。
我的模块太大无法调试,所以我尝试了 Python 文档中的 example module,但出现了不同的问题。这是我的文件和 run.bat
.
的输出
custom.c
#define PY_SSIZE_T_CLEAN
#include <Python.h>
typedef struct {
PyObject_HEAD
/* Type-specific fields go here. */
} CustomObject;
static PyTypeObject CustomType = {
PyVarObject_HEAD_INIT(NULL, 0)
.tp_name = "custom.Custom",
.tp_doc = "Custom objects",
.tp_basicsize = sizeof(CustomObject),
.tp_itemsize = 0,
.tp_flags = Py_TPFLAGS_DEFAULT,
.tp_new = PyType_GenericNew,
};
static PyModuleDef custommodule = {
PyModuleDef_HEAD_INIT,
.m_name = "custom",
.m_doc = "Example module that creates an extension type.",
.m_size = -1,
};
PyMODINIT_FUNC
PyInit_custom(void)
{
PyObject *m;
if (PyType_Ready(&CustomType) < 0)
return NULL;
m = PyModule_Create(&custommodule);
if (m == NULL)
return NULL;
Py_INCREF(&CustomType);
if (PyModule_AddObject(m, "Custom", (PyObject *) &CustomType) < 0) {
Py_DECREF(&CustomType);
Py_DECREF(m);
return NULL;
}
return m;
}
CMakeLists.txt
cmake_minimum_required(VERSION 3.15)
project(module)
add_library(module SHARED custom.c)
target_include_directories(module PRIVATE "C:/Program Files/Python37/include")
target_link_libraries(module "C:/Program Files/Python37/libs/python37_d.lib")
# Output name
set_target_properties(module PROPERTIES PREFIX "")
set_target_properties(module PROPERTIES OUTPUT_NAME "custom")
set_target_properties(module PROPERTIES SUFFIX ".pyd")
run.bat
@echo off
echo ----- Compiling -----
cmake .
cmake --build .
echo.
echo ----- Running -----
python -c "import sys; sys.path.append('Debug'); import custom; print('ok')"
echo Error code: %errorlevel%
输出
Microsoft Windows [Version 10.0.17763.914]
(c) 2018 Microsoft Corporation. All rights reserved.
C:\x\pythontest>run
----- Compiling -----
-- Building for: Visual Studio 16 2019
-- Selecting Windows SDK version 10.0.18362.0 to target Windows 10.0.17763.
-- The C compiler identification is MSVC 19.24.28314.0
-- The CXX compiler identification is MSVC 19.24.28314.0
-- Check for working C compiler: H:/Program Files (x86)/Microsoft Visual Studio/2019/Community/VC/Tools/MSVC/14.24.28314/bin/Hostx64/x64/cl.exe
-- Check for working C compiler: H:/Program Files (x86)/Microsoft Visual Studio/2019/Community/VC/Tools/MSVC/14.24.28314/bin/Hostx64/x64/cl.exe -- works
-- Detecting C compiler ABI info
-- Detecting C compiler ABI info - done
-- Detecting C compile features
-- Detecting C compile features - done
-- Check for working CXX compiler: H:/Program Files (x86)/Microsoft Visual Studio/2019/Community/VC/Tools/MSVC/14.24.28314/bin/Hostx64/x64/cl.exe
-- Check for working CXX compiler: H:/Program Files (x86)/Microsoft Visual Studio/2019/Community/VC/Tools/MSVC/14.24.28314/bin/Hostx64/x64/cl.exe -- works
-- Detecting CXX compiler ABI info
-- Detecting CXX compiler ABI info - done
-- Detecting CXX compile features
-- Detecting CXX compile features - done
-- Configuring done
-- Generating done
-- Build files have been written to: C:/x/pythontest
Microsoft (R) Build Engine version 16.4.0+e901037fe for .NET Framework
Copyright (C) Microsoft Corporation. All rights reserved.
Checking Build System
Building Custom Rule C:/x/pythontest/CMakeLists.txt
custom.c
Creating library C:/x/pythontest/Debug/custom.lib and object C:/x/pythontest/Debug/custom.exp
module.vcxproj -> C:\x\pythontest\Debug\custom.pyd
Building Custom Rule C:/x/pythontest/CMakeLists.txt
----- Running -----
Error code: -1073741819
错误代码-1073741819为0xC0000005,即访问冲突。所以示例代码崩溃了。这是一个与我自己的模块不同的错误,但它可能具有相同的原因。我做错了什么?
我找到了解决方案:我需要在发布模式而不是调试模式下构建,link 到 python37.lib 而不是 python37_d.lib。
我正在用 C++ 制作一个 Python 模块。到目前为止,我使用 MingW 编译模块,效果很好。但我想切换到 MSVC,因为我使用的其他库更易于与 MSVC 一起使用。
但是,我无法让它工作。编译和链接工作正常,但是当我尝试使用来自 Python 的新创建模块时出现问题。我在调用 PyType_Ready
时收到错误 SystemError: Type does not define the tp_name field.
。在Python的源码里看到tp_name
为null的时候报这个错,但是我查了一下不为null。
我的模块太大无法调试,所以我尝试了 Python 文档中的 example module,但出现了不同的问题。这是我的文件和 run.bat
.
custom.c
#define PY_SSIZE_T_CLEAN
#include <Python.h>
typedef struct {
PyObject_HEAD
/* Type-specific fields go here. */
} CustomObject;
static PyTypeObject CustomType = {
PyVarObject_HEAD_INIT(NULL, 0)
.tp_name = "custom.Custom",
.tp_doc = "Custom objects",
.tp_basicsize = sizeof(CustomObject),
.tp_itemsize = 0,
.tp_flags = Py_TPFLAGS_DEFAULT,
.tp_new = PyType_GenericNew,
};
static PyModuleDef custommodule = {
PyModuleDef_HEAD_INIT,
.m_name = "custom",
.m_doc = "Example module that creates an extension type.",
.m_size = -1,
};
PyMODINIT_FUNC
PyInit_custom(void)
{
PyObject *m;
if (PyType_Ready(&CustomType) < 0)
return NULL;
m = PyModule_Create(&custommodule);
if (m == NULL)
return NULL;
Py_INCREF(&CustomType);
if (PyModule_AddObject(m, "Custom", (PyObject *) &CustomType) < 0) {
Py_DECREF(&CustomType);
Py_DECREF(m);
return NULL;
}
return m;
}
CMakeLists.txt
cmake_minimum_required(VERSION 3.15)
project(module)
add_library(module SHARED custom.c)
target_include_directories(module PRIVATE "C:/Program Files/Python37/include")
target_link_libraries(module "C:/Program Files/Python37/libs/python37_d.lib")
# Output name
set_target_properties(module PROPERTIES PREFIX "")
set_target_properties(module PROPERTIES OUTPUT_NAME "custom")
set_target_properties(module PROPERTIES SUFFIX ".pyd")
run.bat
@echo off
echo ----- Compiling -----
cmake .
cmake --build .
echo.
echo ----- Running -----
python -c "import sys; sys.path.append('Debug'); import custom; print('ok')"
echo Error code: %errorlevel%
输出
Microsoft Windows [Version 10.0.17763.914]
(c) 2018 Microsoft Corporation. All rights reserved.
C:\x\pythontest>run
----- Compiling -----
-- Building for: Visual Studio 16 2019
-- Selecting Windows SDK version 10.0.18362.0 to target Windows 10.0.17763.
-- The C compiler identification is MSVC 19.24.28314.0
-- The CXX compiler identification is MSVC 19.24.28314.0
-- Check for working C compiler: H:/Program Files (x86)/Microsoft Visual Studio/2019/Community/VC/Tools/MSVC/14.24.28314/bin/Hostx64/x64/cl.exe
-- Check for working C compiler: H:/Program Files (x86)/Microsoft Visual Studio/2019/Community/VC/Tools/MSVC/14.24.28314/bin/Hostx64/x64/cl.exe -- works
-- Detecting C compiler ABI info
-- Detecting C compiler ABI info - done
-- Detecting C compile features
-- Detecting C compile features - done
-- Check for working CXX compiler: H:/Program Files (x86)/Microsoft Visual Studio/2019/Community/VC/Tools/MSVC/14.24.28314/bin/Hostx64/x64/cl.exe
-- Check for working CXX compiler: H:/Program Files (x86)/Microsoft Visual Studio/2019/Community/VC/Tools/MSVC/14.24.28314/bin/Hostx64/x64/cl.exe -- works
-- Detecting CXX compiler ABI info
-- Detecting CXX compiler ABI info - done
-- Detecting CXX compile features
-- Detecting CXX compile features - done
-- Configuring done
-- Generating done
-- Build files have been written to: C:/x/pythontest
Microsoft (R) Build Engine version 16.4.0+e901037fe for .NET Framework
Copyright (C) Microsoft Corporation. All rights reserved.
Checking Build System
Building Custom Rule C:/x/pythontest/CMakeLists.txt
custom.c
Creating library C:/x/pythontest/Debug/custom.lib and object C:/x/pythontest/Debug/custom.exp
module.vcxproj -> C:\x\pythontest\Debug\custom.pyd
Building Custom Rule C:/x/pythontest/CMakeLists.txt
----- Running -----
Error code: -1073741819
错误代码-1073741819为0xC0000005,即访问冲突。所以示例代码崩溃了。这是一个与我自己的模块不同的错误,但它可能具有相同的原因。我做错了什么?
我找到了解决方案:我需要在发布模式而不是调试模式下构建,link 到 python37.lib 而不是 python37_d.lib。