C++ から Python を扱うことが出来る (その逆も出来る) pybind11 という C++ ライブラリがあるのですが、それで Python の print
をリダイレクトする方法についてのメモです。
問題は、 Windows Desktop Application の場合の対処法。
Windows Desktop Application では、 Console を持っていないため、普通に print("Hello")
とすると、 stdout
が見つからない (None
) というエラーが出力されます。
その場合、一般的な print debug すら困難になるので、それへの対処方法です。
コードとしては以下の通り:
// header #pragma once #include "pch.h" namespace py = pybind11; class PyStdOutRedirect { private: pb::object _stdout; public: explicit PyStdOutRedirect() { const auto sys = py::module::import("sys"); _stdout = sys.attr("stdout"); sys.attr("stdout") = py::module::import("redirect_sys_stdout").attr("stdout_redirect"); } ~PyStdOutRedirect() { const auto sys = py::module::import("sys"); sys.attr("stdout") = _stdout; } } // source #include "pch.h" #include "PyStdOutRedirect.h" PYBIND11_EMBEDDED_MODULE(redirect_sys_stdout, m) { struct StdOutRedirect { StdOutRedirect() = default; StdOutRedirect(const StdOutRedirect&) = default; StdOutRedirect(StdOutRedirect&&) = default; }; py::class_<StdOutRedirect> StdRedirect(m, "stdout_redirect"); StdRedirect.def_static("write", [](const py::object buffer) { std::cout << buffer.cast<std::string>(); }); StdRedirect.def_static("flush", []() { std::cout << std::flush; }); }
あとは、これを任意のブロックやクラスで呼ぶことで、インスタンスが有効な間は std::cout
へと print
の中身が出力されます。
ということで、メモでした。