导入使用Cython构建的库时出现分段错误错误

时间:2019-11-28 05:00:34

标签: c++ python-3.x cython

我有一个用C ++编写的程序,用于生成访问OpenCV,Cuda和Tbb库的边界框。我构建的C ++可执行文件可以在Ubuntu桌面上正常运行。但是,当我尝试将其构建为共享库并使用Cython访问Python中的某些函数时,在尝试导入该库时出现此错误:

Python 3.6.8 (default, Oct  7 2019, 12:59:55) 
[GCC 8.3.0] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> import pyEdges
Segmentation fault (core dumped)

我不知道为什么会显示该错误,尽管我只是导入库,但还没有做其他事情。我所知道的是,在C ++中发生了错误,因为我们试图访问无效的寄存器。有关更多信息:


这是我编写的代码:

c_module.hpp:

#ifndef C_MODULES_HPP
#define C_MODULES_HPP
#include "pch.h"
#include <python3.6/Python.h>

namespace cpp_modules {
class bounding_box {
public:
    int x, y, w, h;
    double score;
    bounding_box();
    bounding_box(int x, int y, int w, int h);
    ~bounding_box();
};

class RegionalEdges {
public:
    vector<bounding_box> BB_result;
    cv::Ptr<StructuredEdgeDetection>  model;
    _para para;
    double accuracy;

    RegionalEdges();
    ~RegionalEdges();

    vector<bounding_box> get_BB(string);
    void setModel(string);
    void setParameter(int, double);
};
}

#endif

c_module.cpp:

#include "c_module.hpp"

namespace cpp_modules{
    bounding_box::bounding_box() {}

    bounding_box::bounding_box(int x, int y, int w, int h) {
        this->x = x;
        this->y = y;
        this->w = w;
        this->h = h;
    }

    bounding_box::~bounding_box() {}

    RegionalEdges::RegionalEdges() {}

    RegionalEdges::~RegionalEdges() {}

    vector<bounding_box> RegionalEdges::get_BB(string filename){
        vector<bounding_box> boxes;
        /*Some openCV and Cuda function to get bounding box*/

        return boxes;
    }

    void RegionalEdges::setModel(string modelname){
        model = createStructuredEdgeDetection(modelname);
    }

    void RegionalEdges::setParameter(int max, double IoU){
        // Initialize defaults value parameters 
    }
}

pyEdges.pyx

# distutils: language = c++

from libcpp.vector cimport vector
from libcpp.string cimport string
from cpython.ref cimport PyObject
from cython.operator cimport dereference as deref

cdef extern from "../cpp_source/c_module.hpp" namespace "cpp_modules":
    cdef cppclass bounding_box:
        # Declare members of bounding_box class

    cdef cppclass RegionalEdges:
        # Declare members of RegionalEdges class

cdef class pyBoundingBox:
    # Wrapper for bounding_box class

cdef extern from "<utility>":
    vector[bounding_box]&& move(vector[bounding_box]&&)

cdef class pyBoundingBox_vector:
    # Wrapper for vector[bounding box]

cdef class PyVector:
    # Wrapper for vector[bounding_box]

cdef class pyRegionalEdges:
    cdef RegionalEdges* Reg

    def __cinit__(self):
        self.Reg = new RegionalEdges()

    def __dealloc__(self):
        del self.Reg

    def get_bb(self, filename):
        cdef string s = <string> filename
        cdef bounding_box bb
        cdef pyBoundingBox_vector new_bb
        cdef vector[bounding_box] bbs = self.Reg.get_BB(s)

        retval = pyBoundingBox_vector()
        retval.move_from(move(bbs))

        return retval 

    def set_model(self, modelname):
        cdef string s = <string> modelname
        self.reg.setModel(s)

    def set_parameter(self, maxBox, IoU):
        self.reg.setParameter(self, maxBox, IoU)

setup.py

from distutils.core import setup

from Cython.Build import cythonize

setup(
    name="pyEdges Wrapper",
    ext_modules=cythonize("pyEdges.pyx", 
    include_path=["cpp_source/build/"]) #The location where I built my C++ shared library
    )

我使用此命令运行setup.py,它可以正常运行。

python3 setup.py build_ext --inplace

我刚刚开始研究Cython,对它如何处理C ++和Python之间的内存管理一无所知。我想包装C ++代码时错过了一步。可能有人可以告诉我是什么问题,或者是有关如何获取有关该错误的更多信息的提示?当C ++中发生分段错误时,我可以使用gdb获取stacktrace,但我不知道如何在Python中使用它。

编辑:

几次尝试再次导入该库后,我终于收到另一条错误消息:

Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
ImportError: /home/amirul/Programming/C++/ROInov/PyWrapper/pyEdges.cpython-36m-x86_64-linux-gnu.so: undefined symbol: _ZN11cpp_modules13RegionalEdges6get_BBENSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE

有人知道这意味着什么吗?

0 个答案:

没有答案