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