如何在pybind11中将共享指针列表传递给C ++对象

时间:2019-11-16 12:18:47

标签: python c++ pybind11

我正在构建一个ml项目,该项目将使用tensorflow,由c ++库和python播放器控制的游戏规则集。

我决定将pybind用作游戏规则引擎和玩家控制层之间的转换层。

这是我尝试用pybind包装的类:

class Player
{
public:
  Player() = default;
  virtual PlayerId getId() const = 0;
  virtual void playTurn(Turn&) = 0;
  virtual void takeHint(std::list<CardId>, Color) = 0;
  virtual void takeHint(std::list<CardId>, Value) = 0;
  virtual ~Player() = default;
};

using Players = std::list<std::shared_ptr<Player>>;

class Game
{
(...)
public:
  Game(const Game&) = delete;
  Game(Game&&) = delete;
  Game(const Players& players, const Cards&);
  void turn();
  int getScore() const;
};

这是我的包裹方式:

PYBIND11_MODULE(hanabi_py, m)
{
  m.doc() = "hanabi-cpp wrapper for python";
  py::class_<Game>(m, "Game")
    .def(py::init<const Players&, const Cards&>())
    .def("turn", &Game::turn)
    .def("getScore", &Game::getScore);

  py::class_<Player, std::shared_ptr<Player>, PyPlayer>(m, "Player")
    .def(py::init<>())
    .def("getId", &Player::getId, "Get id")
    .def("playTurn", &Player::playTurn, "Play turn", py::arg("turn"))
    .def("takeHint",
         py::overload_cast<std::list<CardId>, Color>(&Player::takeHint),
         "take color hint")
    .def("takeHint",
         py::overload_cast<std::list<CardId>, Value>(&Player::takeHint),
         "take value hint");

(...)
}

完整代码可在以下网址获得:https://github.com/morynicz/hanabi-cpp

尝试使用以下游戏创建游戏

import hanabi_py as h

class PyPlayer(h.Player):
    def __init__(self, id):
        h.Player.__init__(self)
        self.id = id

    def getId(self):
        return self.id

    def playTurn(self,turn):
        pass

    def takeHint(self, ids, arg):
        pass

def attempt():
        p = PyPlayer(1)
        c = h.Card
        c.id = 0
        c.color = h.Color.Red
        c.value = h.Value.One
        g = h.Game([p],[c])

我得到:

  

TypeError: init ():不兼容的构造函数参数。支持以下参数类型:       1. hanabi_py.Game(arg0:List [Player],arg1:List [Card])

问题 在将C ++类派生的python类的python对象放入列表之前,如何将其包装到shared_ptr中?

我知道我可以尝试添加一些函数来使用shared_ptr包装python对象,但是要记住,已经有shared_ptr持有人在使用,这似乎是个坏主意。 >

编辑: 看来问题不在于shared_ptr,而是在列表中。由于某种原因,它无法正确解决。我尝试为玩家制作一个不透明的类,但是它不起作用

  

TypeError: init ():不兼容的构造函数参数。支持以下参数类型:       1. hanabi_py.Game(玩家:std :: __ cxx11 :: list,std :: allocator>>,卡牌:List [Card])

所以目前的问题是: 如何将python对象列表作为std :: list>从python传递到C ++对象?

1 个答案:

答案 0 :(得分:1)

此行:

const animals = {};
for (const entry of swatches)
    animals[entry.emoji] = entry.color;

c = h.Card 设置为c类型。您需要在Card的构造中添加构造函数.def(py::init<>()),然后执行py::class_<Card>(m, "Card")