python - 即使 _DEBUG 未定义,嵌入式 Python 仍在寻找调试符号
问题描述
我正在尝试将 Python 嵌入到 C++ 应用程序中,并且我需要它作为发布版本运行,因为我只对调试 C++ 代码感兴趣。另外,我没有_d
我需要的所有库的调试版本。我正在使用 Python 3.7.0,在带有 C++11 的 MSVC 2017 中,我没有调试符号的库是 VTK,我通过雇主提供的轮子文件安装了它。如果我尝试自己构建 Python 包装器,我会遇到另一个问题,因此我无法构建调试文件。如果我在调试模式下运行,我无法导入库,而如果我在发布模式下运行,我会遇到更多问题:
Exception thrown at 0x00007FF90841DBC9 (python37_d.dll) in PythonEmbedding.exe: 0xC0000005: Access violation reading location 0x0000000000000025.
C++ 代码:
int main(int argc, char *argv[])
{
PyObject *pIntrospector = NULL;
if (PyVtk_InitIntrospector(pIntrospector) == OK)
{
printf("Initialization succeeded\n");
}
vtkObjectBase *pConeSource = NULL;
if (PyVtk_CreateVtkObject(pIntrospector, "vtkConeSource", pConeSource) == OK)
{
printf("Object creation succeeded\n");
}
return 0;
}
int PyVtk_InitIntrospector(
PyObject *pIntrospector)
{
/* Activating virtual environment */
#ifdef _DEBUG
// For Visual Studio debug builds
const wchar_t *sPyHome = L"venv-dbg";
#else
// For release builds
const wchar_t *sPyHome = L"venv";
#endif
Py_SetPythonHome(sPyHome);
/* Initializing Python environment and setting PYTHONPATH. */
Py_Initialize();
PyRun_SimpleString("import sys\nimport os");
PyRun_SimpleString("sys.path.append( os.path.dirname(os.getcwd()) )");
PyRun_SimpleString("sys.path.append(\".\")");
PyRun_SimpleString("import importlib.machinery as m");
PyRun_SimpleString("print(m.all_suffixes())");
/* Decode module from its name. Returns error if the name is not decodable. */
PyObject *pIntrospectorModuleName = PyUnicode_DecodeFSDefault("Introspector");
if (pIntrospectorModuleName == NULL)
{
fprintf(stderr, "Fatal error: cannot decode module name\n");
return PYTHON_INTROSPECTION_STRING_DECODE_ERROR;
}
/* Imports the module previously decoded. Returns error if the module is not found. */
PyObject *pIntrospectorModule = PyImport_Import(pIntrospectorModuleName);
if (pIntrospectorModule == NULL)
{
if (PyErr_Occurred())
{
PyErr_Print();
}
fprintf(stderr, "Failed to load \"Introspector\"\n");
Py_DECREF(pIntrospectorModuleName);
return PYTHON_INTROSPECTION_MODULE_LOAD_ERROR;
}
/* Looks for the Introspector class in the module. If it does not find it, returns and error. */
PyObject* pIntrospectorClass = PyObject_GetAttrString(pIntrospectorModule, "Introspector");
if (pIntrospectorClass == NULL || !PyCallable_Check(pIntrospectorClass))
{
if (PyErr_Occurred())
{
PyErr_Print();
}
fprintf(stderr, "Cannot find class \"Introspector\"\n");
if (pIntrospectorClass != NULL)
{
Py_DECREF(pIntrospectorClass);
}
Py_DECREF(pIntrospectorModuleName);
Py_DECREF(pIntrospectorModule);
return PYTHON_INTROSPECTION_CLASS_NOT_FOUND_ERROR;
}
/* Instantiates an Introspector object. If the call returns NULL there was an error
creating the object, and thus it returns error. */
pIntrospector = PyObject_CallObject(pIntrospectorClass, NULL);
if (pIntrospector == NULL)
{
if (PyErr_Occurred())
{
PyErr_Print();
}
fprintf(stderr, "Introspector instantiation failed\n");
Py_DECREF(pIntrospectorModuleName);
Py_DECREF(pIntrospectorModule);
Py_DECREF(pIntrospectorClass);
return PYTHON_INTROSPECTION_OBJECT_CREATION_ERROR;
}
/* Decreasing reference to local data. */
Py_DECREF(pIntrospectorModuleName);
Py_DECREF(pIntrospectorModule);
Py_DECREF(pIntrospectorClass);
return OK;
}
我没有将代码添加到PyVtk_CreateVtkObject
函数中,因为它不会输入它,但是如果我不添加调用之后PyVtk_InitIntroepsctor
它不会给出上述错误。最后,如果我import Introspector
自己在 Python 解释器中,它工作正常。
是否有解决方案可以在 Debug 或 Release 中运行它?我无法绕开它......
PS:我已经尝试过使用 Boost::Python,我有两个问题,因为它也给我带来了问题。
更新 1:特别是,当我这样做时会抛出异常:
PyObject *pIntrospectorModule = PyImport_Import(pIntrospectorModuleName);
更新 2:我已将问题进一步缩小到此:每当我vtk
从嵌入式解释器中导入包时,它都会在此代码上引发访问冲突:
// Add special attribute __vtkname__
PyObject *s = PyString_FromString(classname);
PyDict_SetItemString(pytype->tp_dict, "__vtkname__", s);
Py_DECREF(s); // <-- In particular on this Py_DECREF
如果我尝试导入其他任何东西,似乎没有问题。
解决方案
推荐阅读
- reactjs - 为ios构建本机反应后出错
- php - 正在显示缓存的图像,任何人都可以给我解决方案
- javascript - 表示下一个抛出错误,因为下一个未定义
- android - Android Auto 文本大小不起作用
- javascript - JS:在新页面打开时播放音频
- c# - WPF C#在鼠标移动时绘制平滑矩形而不缺少黑色外部区域
- html - HTML 调整页面大小以适应任何尺寸的显示器
- java - 查看 MVC 架构 NullPointerException
- ethereum - geth 永远不会停止在 rinkeby 测试网上同步
- ajax - 拉拉维尔。AJAX 不适用于 apache