问题描述
我正在尝试将 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
之后添加调用,它不会给出上述错误。最后,如果我自己在 Python 解释器中 import Introspector
,它工作正常。
是否有在 Debug 或 Release 中运行它的解决方案?我无法绕过它...
P.S.:我已经尝试使用 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
如果我尝试导入其他任何东西,似乎没有问题。
解决方法
暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!
如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。
小编邮箱:dio#foxmail.com (将#修改为@)