Странное поведение с pybind11, вызывается неправильная функция - PullRequest
0 голосов
/ 18 июня 2019

решено: необходимо 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
>>>

По какой-то причине только во втором случае вызывается правильная функция (что подтверждается тем, что печатается «ЗДЕСЬ». Я не знаю, что происходит.

Исходный код:

#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().

Он просит меня добавить больше деталей, но я не знаю, что еще сказать, компилятор помечает IЯ использую: -O3 -Wall -shared -std=c++11.

редактировать: добавив py::scoped_ostream_redirect, я получаю печатать "ЗДЕСЬ" последовательно. Все еще не знаю, почему происходит segfault.

edit2: Попробовал, следуя тому, что написано здесь . Переключился на инициализацию с py::array_t и с использованием py::capsule, который ничего не делает. Это помогло, но все равно получало ошибку при попытке напечатать m после выполнения m=reader.get(); reader.next(); m=reader.get()

...