使用boost python和numpy进行分段错误

时间:2016-11-09 15:25:25

标签: python c++ numpy boost

我有一个boost::python库并且正在使用numpy( not boost::numpy)。我的Python脚本使用我的库和函数没有任何问题。但是,当我的脚本结束时,numpy segfaults。我试图生成一个显示问题的MWE。

以下python脚本有时会在完成后

test.py

import arrayTest

arr = arrayTest.getTestArray()

print(arr)

pythonModule.cpp

#include <boost/python.hpp>

#define NPY_NO_DEPRECATED_API NPY_1_7_API_VERSION
#include <numpy/ndarrayobject.h>

#include <vector>

namespace detail
{
    #if PY_MAJOR_VERSION >= 3
    inline void* init() 
    {
        import_array();
    }
    #else
    inline void init()
    {
        import_array();
    }
    #endif
}


boost::python::object getNPArray()
{
    using namespace boost::python;

    auto data = std::vector<double>(2*3*4);
    data.at(6) = 12;

    npy_intp shape[3] = { 2,3,4 };

    PyObject* obj = PyArray_New(
        &PyArray_Type, 
        3, 
        shape, 
        NPY_DOUBLE, 
        nullptr, 
        data.data(), 
        0, 
        NPY_ARRAY_FARRAY, 
        nullptr);

    handle<> handle( obj );

    numeric::array arr( handle );

    return arr.copy();
}

BOOST_PYTHON_MODULE(arrayTest)
{
    detail::init();

    using namespace boost::python;

    numeric::array::set_module_and_type(
            "numpy", 
            "ndarray");   

    def("getTestArray", &getNPArray);
}

为了便于您编译,我还准备了一个cmake脚本:

CMakeLists.txt

cmake_minimum_required(VERSION 3.6 FATAL_ERROR)

project("testArray")

set(Boost_USE_STATIC_LIBS OFF)
set(Boost_USE_MULTITHREADED ON)
set(Boost_USE_STATIC_RUNTIME OFF)
find_package(Boost COMPONENTS python3 REQUIRED)
find_package(PythonLibs 3 REQUIRED)

# If you have your own findNumpy you can remove this part
find_package(PythonInterp 3)

if(PYTHON_EXECUTABLE)
    execute_process(
        COMMAND "${PYTHON_EXECUTABLE}" -c "try:  import numpy; print(numpy.get_include(), end='')\nexcept:pass\n" OUTPUT_VARIABLE path)

    execute_process(
        COMMAND "${PYTHON_EXECUTABLE}" -c "try:  import numpy; print(numpy.__version__, end='')\nexcept:pass\n" OUTPUT_VARIABLE version)

    find_path(PYTHON_NUMPY_INCLUDE_DIRS numpy/ndarrayobject.h
        HINTS "${path}" "${PYTHON_INCLUDE_PATH}" NO_DEFAULT_PATH)

    if(PYTHON_NUMPY_INCLUDE_DIRS)
        set(PYTHON_NUMPY_VERSION ${version})
    endif()

else()
    message(SEND_ERROR "Python executable not found => Cannot determine numpy location.")
endif()

include(FindPackageHandleStandardArgs)
find_package_handle_standard_args(NumPy REQUIRED_VARS PYTHON_NUMPY_INCLUDE_DIRS VERSION_VAR PYTHON_NUMPY_VERSION)
# end of findNumpy part

include_directories(${PYTHON_INCLUDE_DIRS} ${PYTHON_NUMPY_INCLUDE_DIRS})

set(libs 
    ${Boost_LIBRARIES}
    ${PYTHON_LIBRARIES})

add_library(arrayTest SHARED pythonModule.cpp)
target_link_libraries(arrayTest ${libs})
set_target_properties(arrayTest
    PROPERTIES
        PREFIX "")

修改 在python文档中,我发现了以下内容:

  

如果数据传递给PyArray_NewFromDescr或PyArray_New,则在删除新数组之前,不得释放此内存。

所以也许我需要手动删除数组?我该怎么做?

0 个答案:

没有答案