python - python在调试模式下在c ++中工作,但不在exe文件中
问题描述
我正在研究嵌入在 c++ helloworld 程序中的 Python 代码,必要的附加包含/库目录已正确设置。
当我使用本地 Windows 调试器时,它会正确显示“Hello World”。 但是如果我双击 project.exe,它会说 project.exe 已停止工作。
有谁知道要进行什么样的配置或步骤,以便project.exe
在双击时显示“Hello World”?
代码如下:
主文件
#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;
}
你好世界.py
def printHello():
print("Hello World!")
解决方案
在黑暗中拍摄:
- 您没有检查调用的返回值,特别是返回指针的返回值
- 使用调试器运行与“exe-clicking”方法使用的目录不同
您应该检查pModule
. 我的猜测是,由于您在不同的目录中,因此导入失败,因此PyImport_ImportModule
函数返回NULL
(python 引发异常,但在此上下文中不会,因为这是一个有局限性的 C API)
这是脆弱的(并且可能没用):
sys.path.append('./')
你不知道当前目录是什么。最好使其与当前可执行文件相关,或者使用参数或环境变量进行配置。您可以使其相对于当前可执行文件,请参阅Find current executable's path without /proc/self/exe或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 - 当我使用 freq='H' 时,pd.PeriodIndex 只给我 12 小时的结果
- algorithm - 为什么 NP 中的任何语言都可以在 P 机器上运行?
- c# - C# MVC 视图返回城市和州名而不是 id
- r - 如何从 RStudio 的全局环境中删除包含特定字符的对象?
- vue.js - Vue.js 3 - “在‘vuex’中找不到导出‘createStore’
- linker - 在运行时有条件地修改重定位
- swift - SwiftUI 1.0:在 CoreData 中保存自定义数据类型
- django - 如果他们尝试访问 Django 管理页面,则将非超级用户重定向到登录页面/个人资料页面
- codesign - 在 macOS Big sur 上构建时的 Gatekeeper 致命问题
- varnish - VCL 返回(查找)