pybind11的异常行为,调用了错误的函数

时间:2019-06-18 09:35:10

标签: python c++ pybind11

已解决:需要py::return_value_policy::reference

由于某种原因似乎找不到该功能:

>>> import kaldi_rw
>>> reader = kaldi_rw.Pykread("/path/to/file")
>>> m=reader.get()
Segmentation fault (core dumped)

但是!

>>> import kaldi_rw
>>> reader = kaldi_rw.Pykread("/path/to/file")
>>> reader.close()
True
>>> reader = kaldi_rw.Pykread("/path/to/file")
>>> m = reader.get()  # works!
HERE
>>>reader.close()
True
>>>

由于某种原因,仅在第二种情况下,才调用正确的功能(事实证明是打印了“ HERE”。我不知道发生了什么。

源代码:

#include <pybind11/pybind11.h>
#include <pybind11/numpy.h>

#include "util/common-utils.h"
#include "matrix/kaldi-matrix.h"
#include "base/kaldi-common.h"
#include <iostream>

namespace py=pybind11;
using namespace kaldi;

class Pykread {
public:
  Pykread(const std::string fpath): obj(fpath) {
    ptr = nullptr;
    isdone = false;
  }

  py::array_t<float> get() {
    std::cout<<"HERE\n";
    if (obj.Done()) {
      ptr = new float[1]();
      isdone = true;
      return py::array_t<float>(py::buffer_info(ptr, sizeof(float), py::format_descriptor<float>::format(), 1, {0}, {0}));
    }   
    mat = &(obj.Value());
    ptr = mat->Data();
    int32_t numrows = mat->NumRows(), numcols = mat->NumCols();
    return py::array_t<float>(py::buffer_info(ptr, sizeof(float), py::format_descriptor<float>::format(), 2,
             {numrows, numcols}, {sizeof(float) * numrows, sizeof(float)}));
  }

  void next() {
      obj.Next();
  }

  bool close() {
      if (isdone) delete ptr;
      return obj.Close();
  }

  SequentialBaseFloatMatrixReader obj;
  float* ptr;
  Matrix<BaseFloat>* mat;
  bool isdone;
};

PYBIND11_MODULE(kaldi_rw, m) {
  m.doc() = "pybind11 stuff";

  py::class_<Pykread>(m, "Pykread")
      .def(py::init<std::string>())
      .def("get", &Pykread::get)
      .def("next", &Pykread::next)
      .def("close", &Pykread::close);
}

我不知道对close()的呼叫会产生什么影响。

它要求我添加更多详细信息,但我不知道该说些什么,我正在使用的编译器标志为-O3 -Wall -shared -std=c++11

edit:通过添加py::scoped_ostream_redirect,我得到一致的“ HERE”打印。仍然不知道为什么发生段错误。

edit2:尝试按照here的内容进行操作。从py::array_t切换到使用什么都没做的py::capsule进行初始化。这样做有帮助,但是在执行m

后尝试打印m=reader.get(); reader.next(); m=reader.get()时仍然出现段错误

0 个答案:

没有答案