我目前正在开始使用Python(版本3.5)。对于当前项目,我想通过使用Boost-Python为此函数编写包装器来包含一些C代码(用于模拟)。由于这个模拟器的结果将用于NumPy的计算,我想在C-Code中支持NumPy Arrays。
我编写的包装器实际上工作正常,但是当脚本执行后终止Python解释器时,有时会发生SIGSEGV。我试着研究Boost-Python如何处理内存所有权,但我找不到有用的信息来源。
因此,我想问一下是否有人知道为什么这些SIGSEGV会继续发生。该问题的相关代码如下:
setup.py(我正在使用python setup.py install构建项目)
from setuptools import setup, Extension
import os
import sys
source_path = os.path.dirname(os.path.realpath(sys.argv[0]))
dummy = Extension('dummypackage.dummy',
[os.path.join(source_path, "dummy.cpp")],
include_dirs=[source_path],
library_dirs=['/'],
libraries=['boost_python'],
extra_compile_args=['-g', '-Wno-return-type'])
setup(
name="Dummy Project",
version="1.0",
install_requirements=[
"numpy",
],
ext_modules=[dummy],
)
dummy.cpp
#include "dummy.h"
#include "math.h"
#define SQ(x) ((x)*(x))
namespace mlpmp {
using namespace boost::python;
// Helper function for ND Array conversion
object to_ndarray(double* data, int nd, npy_intp* size){
PyObject *object = PyArray_SimpleNewFromData(nd, size, NPY_DOUBLE, data);
handle<> handle(object);
numeric::array array(handle);
return array.copy();
}
dict Foo::func(dict val){
//Extract the arguments from the python dictionaries
numeric::array a = extract<numeric::array>(val["a"]);
numeric::array b = extract<numeric::array>(val["b"]);
double out_val[2];
//... do some computations with the arrays and store them in out_val
npy_intp size = 2;
dict res;
res["a"] = a.copy();
res["b"] = b.copy();
res["res"] = to_ndarray(out_val, 1, &size);
return res;
}
}
dummy.h
#define PY_ARRAY_UNIQUE_SYMBOL dummy
#define NPY_NO_DEPRECATED_API NPY_1_7_API_VERSION
#include <numpy/arrayobject.h>
#include <boost/python.hpp>
void* init_numpy(){
import_array()
}
namespace mlpmp {
using namespace boost::python;
class Foo {
public:
static dict func(dict val);
};
BOOST_PYTHON_MODULE(dummy){
init_numpy();
numeric::array::set_module_and_type("numpy", "ndarray");
class_<Foo>("Foo")
.def("func", &Foo::func)
.staticmethod("func");
}
}
有趣的是,仅使用“extract”函数访问“val”字典以引起SIGSEGV也足够了。我通过返回一个空数组但仍然访问数据来检查这个。如果我返回一个空数组而不访问“val”字典,一切正常。
最后要提到的一点是,SIGSEGV并不是每次运行都会发生,而是(在我的情况下)每隔三到四次 - 所以如果你想验证问题,你需要重复几次。
如果有人可以帮助我,那就太棒了
最佳, 帕斯卡