C++类成员函数返回PyObject*分段错误
C++ class member function returns PyObject* segmentation fault
在某个生物物理模型的模拟框架内,我有一个C++类,它用一个需要返回PyArrayObject*
的成员函数来实现我的模型。该类在头文件ng_networks.h
中定义,其内容类似于:
#include <stdio.h>
#include <math.h>
#include <Python.h>
#include <numpy/arrayobject.h> /* Numpy as seen from C */
struct ngn{...}; /* Structure of model parameter */
class ngn_rate{ /* Model Class */
int NEQ;
ngn pars;
double *y,*dy;
public:
ngn_rate(); // Constructor
~ngn_rate(); // Destructor
PyObject* bifsystem();
}
ngn_rate::ngn_rate(){
// Set ngn pars default values
...
// Allocate memory for model variables and RHS of equations
y = (double*)calloc(NEQ,sizeof(double));
dy = (double*)calloc(NEQ,sizeof(double));
}
ngn_rate::~ngn_rate{
free(y);
free(dy);
}
PyObject* ngn_rate::bifsystem(){
long int NUMEL = NEQ; // PyArray creation function requires (long int*)
// Does some operations on y,dy
...
// Build PyObject* from dy
// Create Python Array Object...
PyObject* out_array = PyArray_SimpleNew(1,&NUMEL,NPY_DOUBLE);
// ... and make C pointer to point to it
double* dy_aux = (double*)((PyArrayObject*)out_array)->data;
// Copy dy into PyObject out_array
for(int i=0;i<NUMEL;i++) dy_aux[i] = dy[i];
return out_array;
}
正如您可能猜测的那样,这个类最终是从Python模块调用的。在这方面,我使用scipy.weave将我的C代码与Python接口。因此,调用Python模块看起来像:
def ngn_rate_py():
support_code = """
#include <Python.h>
#include "ng_networks.h"
"""
source_files = [...] # A list of C/CPP source file names
libs = ['m']
dirs = [...] # A list of #include dirs
# My C code to interface with Python
code = """
//Initialize Model
ngn_rate network();
//Return dy_dt
return_val = network.bifsystem();
"""
vars = []
dy = weave.inline(code,
vars,
support_code = support_code,
sources = source_files,
libraries = libs,
library_dirs = dirs,
include_dirs = dirs,
runtime_library_dirs = dirs,
type_converters = converters.blitz,
compiler = 'gcc',
extra_compile_args = ['-std=c++11'],
force = 1)
return dy
不幸的是,当我运行上述模块时,它会产生分段故障。经过调试和尝试,我发现问题是由ng_networks.h
中PyObject* out_array
的初始化引起的。事实上,当我在weave
中的C代码中创建PyObject*
时,它非常完美:也就是说,我修改ngn_rate::bifsystem()
类成员函数,使其返回double*
,然后在编织接口中从后者构建PyObject*
class ngn_rate{ /* Model Class */
...
public:
...
double* bifsystem();
}
double* ngn_rate::bifsystem(){
long int NUMEL = NEQ; // PyArray creation function requires (long int*)
// Does some operations on y,dy
...
return dy;
}
然后在weave
接口中:
def ngn_rate_py():
support_code = """
#include <Python.h>
#include "ng_networks.h"
"""
code = """
//Initialize Model
ngn_rate network();
//Create temporary dy
double *dy = network.bifsystem();
//Create PyObject*
PyObject* out_array = PyArray_SimpleNew(1, &NUMEL, NPY_DOUBLE);
double* dy_aux = (double*) ((PyArrayObject*) out_array)->data;
//Assign dy to PyObject
for(int i=0;i<NUMEL;i++) dy_aux[i]=dy[i];
return_val = out_array;
我不明白为什么上面的工作,而如果我让PyObject*
由我的类返回,我会得到一个分段错误。值得注意的是,在其他一些代码中,我只有一个静态/非成员C函数,它返回了一个PyObject*
,当从weave
调用时,它运行得很好。所以我的猜测是,在C类对象中使用PyObject*
存在一些问题。但我不知道是什么。尽管我可以使用上面的代码在weave
接口中创建PyObject*
,但为了可移植性,我宁愿让我的类ngn_rate
直接提供它。
提前感谢您的反馈。
M
如注释所建议的那样,分段错误的解决方案是确保初始化Python-C API和Numpy数组。这可以通过Py_Initialize()
和import_array()
宏来完成,它们适时地包含在类ngn_rate
的构造函数中,即
#include <Python.h>
#include <numpy/arrayobject.h>
class ngn_rate{
...
public:
ngn_rate();
...
};
ngn_rate::ngn_rate{
Py_Initialize();
import_array();
...
}
- 在某些循环内使用vector.push_back时出现分段错误
- 为什么在运行时没有向我们提供有关分段错误的更多信息?
- 如何解决gcc编译器优化导致的centos双编译器设置中的分段错误
- 当我的阵列太大时出现分段错误
- 分段错误当我试图运行程序时出错
- 在c++中初始化矩阵时出现分段错误(核心转储)
- 尝试使用集合函数时出现分段错误
- 我无法缩小此分段错误的原因
- g++的分段错误(在NaN上使用to_string两次时)
- 我是如何在这段代码中出现分段错误的
- 创建结构的数组时遇到分段错误
- 在c++中键入向量中的所有值后,得到分段错误(核心转储)
- 在 c++ 中实现 Trie 时出现分段错误
- 为什么 fstream 在打开带有格式的文件时会导致分段错误?
- 为什么我遇到分段错误?
- 动态类的分段错误(家庭作业问题)
- 分段错误 - 读取初始化指针的数组
- 如何摆脱C ++中的分段错误错误?
- 使用 CTYPE 时出现分段错误
- 为什么代码给出分段错误?