- c - 在位数组中找到第一个零
- linux - Unix 显示有关匹配两种模式之一的文件的信息
- 正则表达式替换多个文件
- linux - 隐藏来自 xtrace 的命令
(抱歉,标题含糊不清,但它表明我对这个问题感到震惊)。
因此,我按照此处描述的方法从 C++ 程序运行 Python 代码:https://docs.python.org/2/extending/embedding.html .
C++代码如下:
#include <Python.h>
#include <iostream>
int main(int argc, char *argv[])
{
PyObject *pName, *pModule, *pDict, *pFunc;
PyObject *pArgs, *pValue;
int i;
if (argc < 3) {
fprintf(stderr,"Usage: call pythonfile funcname [args]\n");
return 1;
}
Py_SetProgramName(argv[0]);
Py_Initialize();
PySys_SetArgv(argc, argv);
PyObject *sys = PyImport_ImportModule("sys");
PyObject *path = PyObject_GetAttrString(sys, "path");
PyList_Append(path, PyString_FromString("."));
pName = PyString_FromString((char*)argv[1]);
/* Error checking of pName left out */
pModule = PyImport_Import(pName);
Py_DECREF(pName);
if (pModule != NULL) {
pFunc = PyObject_GetAttrString(pModule, argv[2]);
/* pFunc is a new reference */
if (pFunc && PyCallable_Check(pFunc)) {
PyObject *pArgs = PyList_New(4);
PyList_SetItem(pArgs,0,PyString_FromString("H-SAMPLE1-OH"));
PyList_SetItem(pArgs,1,PyInt_FromLong(2));
PyList_SetItem(pArgs,2,PyString_FromString("H-SAMPLE2-OH"));
PyList_SetItem(pArgs,3,PyInt_FromLong(3));
PyObject *arglist = Py_BuildValue("(O)", pArgs);
Py_DECREF(pArgs);
for(int run = 0; run < 2; run++)
{
std::cout << "begin" << std::endl;
pValue = PyObject_CallObject(pFunc, arglist);
//Py_DECREF(arglist);
if (pValue != NULL)
{
int py_list_size = PyList_Size(pValue);
printf("list size = %d\n",py_list_size);
int sub_list_size = 0;
for(Py_ssize_t i = 0; i < py_list_size; ++i)
{
PyObject *pList = PyList_GetItem(pValue, i);
sub_list_size = PyList_Size(pList);
if(PyList_Check(pList))
{
for(Py_ssize_t j = 0; j < sub_list_size; ++j)
{
PyObject *pListItem = PyList_GetItem(pList, j);
double pyNumber = PyFloat_AsDouble(pListItem);
std::cout << "pynumber ok" << std::endl;
Py_DECREF(pListItem);
printf("Result of call: %f\n", pyNumber);
}
}
else
{
printf("Not list!\n");
}
Py_DECREF(pList);
}
Py_DECREF(pValue);
}
else {
std::cout << "Else" << std::endl;
Py_DECREF(pFunc);
Py_DECREF(pModule);
PyErr_Print();
fprintf(stderr,"Call failed\n");
return 1;
}
}
}
else {
if (PyErr_Occurred())
PyErr_Print();
fprintf(stderr, "Cannot find function \"%s\"\n", argv[2]);
}
Py_XDECREF(pFunc);
Py_DECREF(pModule);
}
else {
PyErr_Print();
fprintf(stderr, "Failed to load \"%s\"\n", argv[1]);
return 1;
}
Py_Finalize();
return 0;
}
这是玩具 Python 代码:
def test(a):
print a
return [[1.2,2.6],[4.7,5.6]]
注意 C++ 代码中的主循环,迭代变量“run”。当循环内的代码只执行一次时,它就像一个魅力。如果我尝试运行它更多次,例如只运行两次,它就会出错,我会遇到段错误。显然,错误发生在第 61 行,当尝试执行
double pyNumber = PyFloat_AsDouble(pListItem);
我觉得很奇怪。它在第一次执行期间工作正常,然后突然 if 不再设法从 pListItem 正确获取某些内容(尽管它确实收到了它识别为大小为 2 的列表的内容并且似乎正确处理了所有其他 pyObject 指针)。知道发生了什么事吗?
重现:
我编译如下:
g++ -L/usr/lib/python2.7/config-x86_64-linux-gnu -L/usr/lib -I/usr/include/python2.7 -o ms2pip ms2pip.c -lpthread -ldl -lutil -lm -lpython2.7 -Xlinker -export-dynamic -Wl,-O1 -Wl,-Bsymbolic-functions
然后执行如下:
$ ./ms2pip python_code test
(so ./executable < python_file_without_py_extension > < function_name >)
最佳答案
我认为你的问题是 PyList_GetItem()返回借用的引用。所以问题在于用 pList
和 pListItem
调用 Py_DECREF()
:
PyObject *pList = PyList_GetItem(pValue, i);
// ...
if(PyList_Check(pList))
{
for(Py_ssize_t j = 0; j < sub_list_size; ++j)
{
PyObject *pListItem = PyList_GetItem(pList, j);
double pyNumber = PyFloat_AsDouble(pListItem); // <-- Segfault in second iteration after released from first iteration.
// ...
Py_DECREF(pListItem); // <-- Bad, released in first iteration.
// ...
}
}
//...
Py_DECREF(pList); // <-- Bad, released in first iteration.
pList
是借用的引用,您不负责使用 Py_DECREF()
释放它。此外,pListItem
也是借用的引用。因此,在第一次迭代中,您释放了 pList
以及每个不好的 pListItem
。在第二次迭代中,您获取已发布的 pList
和每个 pListItem
并将它们视为仍然稳定,但事实并非如此。因为您正在访问已释放的对象,程序可能真的会失败或在涉及它们的任何函数调用中给出错误的结果(例如,PyList_Size(pList)
、PyList_GetItem(pList, j)
, PyFloat_AsDouble(pListItem)
, Py_DECREF(pListItem)
, Py_DECREF(pList)
).
关于python - 在 C++ 中嵌入 python : strange segmentation faults,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28302709/
我在一个俄罗斯编程论坛上遇到了这个问题,但还没有想出一个优雅的解决方案。 问题: 你有一个包含N个正整数的数组,你需要将它分成M个连续的段,使得最大段的和是可能的最小值。通过段的总数,我的意思是它所有
我正在从文本“从 0 到 1 的操作系统”中学习链接脚本,并且在文本中他们展示了一个使用关键字 PHDRS 的示例; ENTRY(main); PHDRS { headers PT_P
一个小型测试程序在 64 位 Linux 上使用 gfortran (4.4.5) 返回段错误。 n=2_8**22_8 时不存在故障。 gdb 指示在循环的第一次迭代期间函数 mylen 中发生段错
我正在尝试计算一个比率,当我的分子数组充满 0 时它可以工作,但是当我在分子数组中有值时会中断程序。 223 Double_t *ratio_calculations(int bin_numbers,
我正在研究组合分页/分段系统,在我的书中有两种方法: 1.paged segmentation 2.segmented paging 我无法弄清楚两者之间的区别。我认为在分页分段中,段被分成页面,在分
语义分割只是一种重复,还是“语义分割”和“分割”之间有区别? “场景标记”和“场景解析”有区别吗? 像素级分割和像素级分割有什么区别? (附带问题:当您拥有这种逐像素注释时,您是否可以免费获得对象检测
我遇到了一个非常奇怪的行为,我正在遵循在线文档,并且在创建一个段来与我的子段一起使用时,lambda 按以下顺序执行: xray_recorder.begin_segment('segment-nam
我们正在我们的服务器上进行一些负载测试,我正在使用 tshark 将一些数据捕获到 pcap 文件,然后使用 wireshark GUI 通过转到 Analyze -> expert Info 来查看
我是一名高中生,今年开始学习汇编。 我目前正在制作 Pacman 克隆作为我的最终项目。 我遇到的唯一问题是我的代码很大,*.exe 文件几乎有 64KB。 所以我的问题是,如果我转向模型介质,我需要
前言 本系列文章是博主在工作中使用SAM模型时的学习笔记,包含三部分: SAM初步理解,简单介绍模型框架,不涉及细节和代码 SAM细节理解,对各模块结合代码进一步分析 SAM微调实例
我很困惑进程在使用虚拟内存时如何可能出现段错误。据我了解,“虚拟”内存允许进程访问所有可用内存,然后将其映射到“实际”硬件内存。通过这种转换,进程怎么可能尝试访问不允许访问的内存部分? 最佳答案 听起
Tritwise操作(向右旋转和疯狂操作)无法正确运行,并在Malbolge编译器/解释器中引发分段错误。 在看到有关Coding Challenges和Code Golf的惊人答案之后,我决定开始在
只是有关DirectX11镶嵌的问题。 在“船体着色器”中,可以设置的最大镶嵌因子为64(不确定原因)。现在,尽管对于小型飞机已经足够了,但是对于大型飞机来说,这还远远不够,所以我想知道如何渲染大型飞
我需要在 matlab 中手动分割图像。我很想使用“impoly”,但我主要需要分割圆形对象。 我在 Youtube 上的 Ali Pashaei 视频中找到了我需要的东西,在“FlowImagePr
我有下面的代码。当我取消注释 temperature(i,j) = anode_temperature 时,我会出现 SegFault。 forall(i=0:Cells(1), j=0:Cells(
我是 C 编程新手,我的代码中出现了段错误。该程序使用返回函数来询问用户他们的银行帐户中有多少钱。稍后我将添加代码来计算利息。感谢您为我查看此内容,因为我很难找出为什么会出现此错误。 #include
为了测试,我编写了一个代码来计算 #include int main(void) { int p, i, primes[50], index; boo
这个问题已经有答案了: What is a segmentation fault? (17 个回答) 已关闭 5 年前。 最近我开始研究内置函数,但遇到了一个错误,那就是: 为什么我会遇到此程序段错误
已关闭。此问题需要 debugging details 。目前不接受答案。 编辑问题以包含 desired behavior, a specific problem or error, and the
注意:我们有很多段错误,基本相同 答案,所以我试图将其分解为一个规范的问题,例如 我们有undefined reference。 尽管我们有一个关于what a segmentati
我是一名优秀的程序员,十分优秀!