// Compile with: // mkoctfile --link-stand-alone embedded.cc -o embedded #include #include #include #include #include int run_some_octave_code_with_output () { octave::interpreter interpreter; int status = -1; try { status = interpreter.execute (); if (status != 0) { std::cerr << "creating embedded Octave interpreter failed!" << std::endl; return status; } octave_idx_type n = 2; octave_value_list in; for (octave_idx_type i = 0; i < n; i++) in(i) = octave_value (5 * (i + 2)); octave_value_list out = octave::feval ("gcd", in, 1); if (out.length () > 0) std::cout << "GCD of [" << in(0).int_value () << ", " << in(1).int_value () << "] is " << out(0).int_value () << std::endl; else std::cout << "invalid\n"; // Bad function call octave_value_list bad_in; octave::feval ("gcd", bad_in, 1); } catch (const octave::exit_exception& ex) { std::cerr << "Octave interpreter exited with status = " << ex.exit_status () << std::endl; } catch (const octave::execution_exception&) { std::cerr << "error encountered in Octave evaluator!" << std::endl; } return status; } int main (void) { // see https://stackoverflow.com/questions/5419356/redirect-stdout-stderr-to-a-string // and https://en.cppreference.com/w/cpp/io/basic_ios/rdbuf std::stringstream buffer_cout; std::stringstream buffer_cerr; // remember old buffers auto old_cout = std::cout.rdbuf(); auto old_cerr = std::cerr.rdbuf(); // set our buffers std::cout.rdbuf(buffer_cout.rdbuf()); std::cerr.rdbuf(buffer_cerr.rdbuf()); int status = run_some_octave_code_with_output (); // restore usual cout and cerr std::cout.rdbuf(old_cout); std::cerr.rdbuf(old_cerr); // grab buffer contents std::string text_cout = buffer_cout.str(); std::string text_cerr = buffer_cerr.str(); std::cout << std::endl << std::endl << "My message first" << std::endl << "----------------" << std::endl << std::endl; std::cout << "COUT $$$$ " << text_cout << std::endl << std::endl; std::cout << "CERR $$$$ " << text_cerr << std::endl << std::endl; return status; }