pybind / pybind11

Seamless operability between C++11 and Python
https://pybind11.readthedocs.io/
Other
15.7k stars 2.1k forks source link

Create imported python object in C++ #40

Closed mrzv closed 8 years ago

mrzv commented 8 years ago

I'd like to create a Python object from a Python module I import within C++. The code would probably explain it best:

    auto threading = py::module::import("threading");
    py::object Thread = threading.attr("Thread");
    py::function f = py::cast([]() { std::cout << "Hello" << std::endl; });
    m.attr("t") = Thread.call(Py_None, f);

The first three lines work fine, but the last one doesn't.

The error I get (within Python) is:

terminate called after throwing an instance of 'pybind11::cast_error'
  what():  handle::call(): unable to convert input arguments to Python objects

The equivalent Python code works fine:

import threading
def f(): print "Hello"
t = threading.Thread(None,f)
wjakob commented 8 years ago

Hi Dmitry,

I added some generalizations (which actually turned out to be simplifications) to the caster implementation. Now you can do this (note the minor differences to your example)

    auto threading = py::module::import("threading");
    py::object Thread = threading.attr("Thread");
    py::cpp_function f ([]{ std::cout << "Hello" << std::endl; });
    m.attr("t") = Thread.call(nullptr, f);
mrzv commented 8 years ago

Yup, works great. Thanks.

BTW, the reason I'm doing this is that I want to open a nanogui viewer (a Screen really) in the background and to interact with it from Python. But I cannot put it in a separate std::thread. If I put the init, mainloop, etc in a separate thread everything crashes. I realize here is not the place to report that, and it's a non-issue for me now -- spinning a Python thread and releasing GIL works well.

wjakob commented 8 years ago

closing the pybind11 part of this ticket.