主にプログラミング関連のメモ帳 ♪(✿╹ヮ╹)ノ
書いてあるコードは自己責任でご自由にどうぞ。記事本文の無断転載は禁止です。
2022/09/07
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
の中身が出力されます。
ということで、メモでした。