Проблема и решение
В вашем примере есть несколько проблем, самая важная из которых состоит в том, что ваши указатели недействительны, поскольку они указывают на то, что выходит за рамки (ваш аргумент s
class SS
).
Решение состоит в том, чтобы скопировать s
в переменную-член class SS
следующим образом:
#include <string>
#include <iostream>
#include <pybind11/pybind11.h>
namespace py = pybind11;
class SS {
public:
SS(const std::string& s) : m_data(s) {}
const char* data() const { return m_data.data(); }
std::string m_data;
};
class PySS: public SS {
public:
PySS(const std::string& s): SS(s) {}
std::string get() { return std::string(SS::data()); }
};
PYBIND11_MODULE(example, m)
{
py::class_<PySS>(m, "SS")
.def(py::init<const std::string&>())
.def("get", &PySS::get);
}
Еще два замечания:
- В вашем примере отсутствует макрос
PYBIND11_MODULE
, который заботится о некоторых общих вещах, чтобы можно было импортировать ваш модуль (см. этот пример ). - Я бы никогда не объявилта же функция с двумя различными значениями: ваш
SS::data()
возвращает указатель, а PySS::data()
возвращает копию (std::string
).Таким образом, я переименовал последнее в PySS::get()
, чтобы сделать различие ясным.
Обходной путь для сторонних классов
Учитывая, что вы class SS
это вне вашего контроля, я думаю, что вы можете обойти проблему, только обернув ее.Например:
#include <string>
#include <iostream>
#include <pybind11/pybind11.h>
namespace py = pybind11;
class SS {
public:
SS() = default;
SS(const std::string& s) : data_(s.data()), size_(s.size()) {}
const char* data() const { return data_; }
private:
const char* data_;
size_t size_;
};
class PySS {
public:
PySS(const std::string& s) { m_data = s; m_SS = SS(m_data); }
std::string get() { return std::string(m_SS.data()); }
private:
std::string m_data;
SS m_SS;
};
PYBIND11_MODULE(example, m)
{
py::class_<PySS>(m, "SS")
.def(py::init<const std::string&>())
.def("get", &PySS::get);
}