python 在调试模式下在 c++ 中工作,但在 exe 文件中不工作
python works in c++ in debug mode, but not in exe file
我正在研究一个 Python 代码嵌入到 c++ helloworld 程序中,
必要的额外 include/library 目录已正确设置。
当我使用本地 Windows 调试器时,它会正确显示 "Hello World"。
但是如果我双击 project.exe,它说 project.exe 已停止工作。
有谁知道要进行什么样的配置或步骤才能使 project.exe
在双击时显示 "Hello World"?
代码如下:
main.cpp
#include <iostream>
#include <Python.h>
#include <string.h>
#include <stdlib.h>
using namespace std;
int main()
{
Py_Initialize();
PyRun_SimpleString("import sys");
PyRun_SimpleString("sys.path.append('./')");
PyObject *pModule = PyImport_ImportModule("helloworld");
PyObject *pFunc = PyObject_GetAttrString(pModule, "printHello");
PyEval_CallObject(pFunc, NULL);
Py_Finalize();
return 0;
}
helloworld.py
def printHello():
print("Hello World!")
在黑暗中拍摄:
- 您没有检查调用的 return 值,特别是那些 returning 指针
- 运行 调试器未使用与 "exe-clicking" 方法相同的目录
您应该检查 pModule
的 return 值。我的猜测是因为你在不同的目录中,导入失败,所以 PyImport_ImportModule
函数 returns NULL
(python 引发异常,但不是在这种情况下因为这是一个 C API 有其局限性)
这很脆弱(可能没用):
sys.path.append('./')
您不知道当前目录是什么。最好让它相对于当前的可执行文件,或者使用参数或环境变量进行配置。您可以使其相对于当前的可执行文件,请参阅 Finding current executable's path without /proc/self/exe or Get path of executable
现在,当您尝试使用此空指针时,程序会崩溃。从这个开始:
PyObject *pModule = PyImport_ImportModule("helloworld");
if (pModule == NULL)
{
std::cout << "could not import module\n";
exit(1);
}
(属性获取也是如此:始终保护您的调用,或者更好:将它们包装在抛出异常的 C++ 方法中)。
#include <string>
#include <stdexcept>
PyObject *safe_PyImport_ImportModule(const std::string &module_name)
{
PyObject *pModule = PyImport_ImportModule(module_name.c_str());
if (pModule == NULL) // c++11 purists would put "nullptr"
{
std::cout << "cannot import " << module_name << '\n';
throw std::runtime_error("Import error: "+module_name);
}
return pModule;
}
我正在研究一个 Python 代码嵌入到 c++ helloworld 程序中, 必要的额外 include/library 目录已正确设置。
当我使用本地 Windows 调试器时,它会正确显示 "Hello World"。 但是如果我双击 project.exe,它说 project.exe 已停止工作。
有谁知道要进行什么样的配置或步骤才能使 project.exe
在双击时显示 "Hello World"?
代码如下:
main.cpp
#include <iostream>
#include <Python.h>
#include <string.h>
#include <stdlib.h>
using namespace std;
int main()
{
Py_Initialize();
PyRun_SimpleString("import sys");
PyRun_SimpleString("sys.path.append('./')");
PyObject *pModule = PyImport_ImportModule("helloworld");
PyObject *pFunc = PyObject_GetAttrString(pModule, "printHello");
PyEval_CallObject(pFunc, NULL);
Py_Finalize();
return 0;
}
helloworld.py
def printHello():
print("Hello World!")
在黑暗中拍摄:
- 您没有检查调用的 return 值,特别是那些 returning 指针
- 运行 调试器未使用与 "exe-clicking" 方法相同的目录
您应该检查 pModule
的 return 值。我的猜测是因为你在不同的目录中,导入失败,所以 PyImport_ImportModule
函数 returns NULL
(python 引发异常,但不是在这种情况下因为这是一个 C API 有其局限性)
这很脆弱(可能没用):
sys.path.append('./')
您不知道当前目录是什么。最好让它相对于当前的可执行文件,或者使用参数或环境变量进行配置。您可以使其相对于当前的可执行文件,请参阅 Finding current executable's path without /proc/self/exe or Get path of executable
现在,当您尝试使用此空指针时,程序会崩溃。从这个开始:
PyObject *pModule = PyImport_ImportModule("helloworld");
if (pModule == NULL)
{
std::cout << "could not import module\n";
exit(1);
}
(属性获取也是如此:始终保护您的调用,或者更好:将它们包装在抛出异常的 C++ 方法中)。
#include <string>
#include <stdexcept>
PyObject *safe_PyImport_ImportModule(const std::string &module_name)
{
PyObject *pModule = PyImport_ImportModule(module_name.c_str());
if (pModule == NULL) // c++11 purists would put "nullptr"
{
std::cout << "cannot import " << module_name << '\n';
throw std::runtime_error("Import error: "+module_name);
}
return pModule;
}