我有一个用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
有人知道这意味着什么吗?