【问题标题】:pybind11::object in pybind11::dictpybind11::dict 中的 pybind11::object
【发布时间】:2019-05-18 17:17:31
【问题描述】:

我尝试将 python 解释器嵌入到我的 C++17 应用程序中。 我必须从 python 访问位于 C++ 世界中的 Foo 的对象实例。

所以我想出了以下代码:

#include <pybind11/embed.h>
#include <pybind11/pybind11.h>
#include <iostream>

namespace py = pybind11;
using namespace py::literals;

class Foo
{
public:
  Foo() : v(42) {}
  int get() const { return v; }
  void set(int x) { v = x; }
private:
  int v;
};

PYBIND11_EMBEDDED_MODULE(my_module, m) {
    py::class_<Foo>(m, "Foo")
      .def(py::init<>())
      .def("get", &Foo::get)
      .def("set", &Foo::set);
}

int main()
{
  py::scoped_interpreter guard{};
  using namespace py::literals;

  py::object py_foo = py::cast(Foo());
  auto locals = py::dict(
    "foo"_a = py_foo            // (line of evil)
  );

  // CRASH!
  try {
    py::exec("print(foo.get())", py::globals(), locals);
    return EXIT_SUCCESS;
  } catch (const std::exception& e) {
    std::cerr << e.what() << std::endl;
    return EXIT_FAILURE;
  }
}

运行时崩溃:Unable to convert call argument 'foo' of type 'object' to Python object

文档仅显示如何将intstring 插入py::dict

我猜 pybind11 知道 Foo,因为当我删除 (line of evil) 行并将代码替换为 from my_module import Foo; print(Foo().get()) 时,它会达到我的预期(但显然不是我想要的)。

那么,我做错了什么?

【问题讨论】:

    标签: python c++ pybind11


    【解决方案1】:

    在嵌入式 Python 解释器中,需要先导入模块,否则 Python 不知道该模块存在。

    py::module::import("my_module"); 添加到您的main()

    int main()
    {
      py::scoped_interpreter guard{};
    
      py::module::import("my_module");  // <-- Here, import the module
      using namespace py::literals;
    
      py::object py_foo = py::cast(Foo());
      auto locals = py::dict(
    
    // ....
    

    【讨论】:

    • 谢谢!关于如何改进有关文档的任何想法?我没有找到提示。还是我太晕了?
    • @pasbi IDK 在文档中的位置...实际上这有点直观。因为那个宏只定义了一个模块,没有别的。在独立库的情况下,您需要在使用之前从 Python 导入该模块。所以嵌入式案例也是类似的。
    • 当然,现在这对我来说也完全有意义。但是如果你是 pybind11 的新手并且感觉一切都很神奇,那么很难调试。所以我想这样的例子放在文档中是不合适的。请注意,在普通 python 中,您可以使用未直接导入当前范围的模块中的对象(请参阅git.io/fppLV)。也许这会误导我。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-03-05
    • 2020-02-29
    • 2022-01-19
    • 2021-02-13
    • 1970-01-01
    • 2022-06-11
    相关资源
    最近更新 更多