On Linux, you can simply temporarily redirect STDOUT to a temporary file for the duration of the python script.
At the end of the python call you can read the contents of the temporary file and then dump the file.
I'm pretty sure Windows will have a similar mechanism.
Here's a first go with an attempt at some RAII to clean up all the handles.
#include <unistd.h>
#include <cstdio>
#include <stdlib.h>
#include <string>
#include <iostream>
void simulate_python_script() {
std::printf("Written to STDOUT I think");
}
struct auto_fd {
auto_fd(int fd)
: fd_(fd) {}
~auto_fd() {
if (fd_ != -1)
::close(fd_);
}
auto_fd(auto_fd const&) = delete;
auto_fd& operator=(auto_fd const&) = delete;
operator int() const {
return fd_;
}
int fd_;
};
struct file_closer
{
void operator()(FILE* p) const noexcept
{
::fclose(p);
}
};
using auto_fp = std::unique_ptr<FILE, file_closer>;
auto make_auto_fp(FILE* fp)
{
return auto_fp(fp, file_closer());
}
struct push_fd {
push_fd(int target, int new_fd)
: saved_(::dup(target)), target_(target) {
::dup2(new_fd, target);
}
~push_fd() {
if (saved_ != -1) {
::dup2(saved_, target_);
::close(saved_);
}
}
int saved_, target_;
};
int main() {
using namespace std::literals;
auto tempfp = make_auto_fp(::tmpfile());
auto tempfd = auto_fd(::fileno(tempfp.get()));
// redirect STDOUT to the temp file with RAII
{
push_fd fd_save(1, tempfd);
simulate_python_script();
}
// now read the file which Python thought was STDOUT
char buf[256];
while (auto count = ::read(tempfd, buf, 256)) {
if (count < 0) break; // error condition
std::cout.write(buf, count);
}
std::cout << std::endl;
}