I try to redirect all outputs stderr, stdout to C/C++ from julia
Currently I do and it seems to work:
# Create custom IO buffer
const io = IOBuffer()
Base.stdout = io;
# Define function to retrieve buffer contents
function get_output()
return String(take!(copy(io)))
end
# Define function to clear buffer
function clear_output()
truncate(io, 0)
end
jl_eval_string("clear_output()");
jl_eval_string("println(1+1)");
jl_value_t* output = jl_eval_string("get_output()");
if (output)
{
std::string txt = std::string(jl_string_ptr(output));
io->outputMessage(txt); // my internal output
}
result is correctly displayed.
But if I do:
jl_eval_string("1+1");
result of stdout is not in available
I did not found how to redirect this case to a C/C++ stream too
What would you expect in stdout from evaluating 1+1? It doesn’t print anything.
(When you enter an expression at the interactive julia> REPL prompt, it calls display on the result of the expression, which outputs it to stdout. But this isn’t done for expressions evaluated with jl_eval_string.)
Just re-assigning Base.stdout or calling redirect won’t accomplish this, because the default display backend saves a reference to the original stdout. (Also, the whole point of display is that the output can be specific to your enviroment, e.g. some objects might display graphically in Jupyter or Pluto or similar environments.)
The right way to capture display output is to call pushdisplay to push a new display backend to the top of the stack — this will get called first for any code that invokes display(x), allowing you to do whatever you want, displaying objects as text or other supported formats as desired, or capturing the output in a string or array. This is what IJulia does, for example. It’s also what Pluto.jl does.
However, I want to step back a bit. Why are you doing this? Are you creating a new interactive environment for Julia? If not, i.e. for non-interactive use, I wouldn’t recommend communicating with libjulia via strings, and especially not by capturing stdout — better to pass data back and forth directly, in native formats.
Thank you for the help! Let me clarify my goals a bit. I’m exploring this approach as part of building a new environment between Nelson and Julia, where the focus is on enabling seamless integration. My aim is to create a bridge that provides an accessible and user-friendly experience for Nelson’s users who might not be familiar with Julia.
Using strings and capturing stdout is primarily a convenience for this early stage of development, allowing for rapid prototyping and easier debugging.
If you have any specific recommendations or examples of best practices for interfacing with libjulia, I’d love to hear them!
Currently I investigate to do equivalent of python_engine already available in Nelson (equivalent to matlab feature)
I did not add a link on help file of Nelson, since I currently not allowed to add url in comments …
R = jlrun(‘A = 1+ 2’, ‘A’)
will return in R value of A
I also expected to have jlrun(‘1+ 2’) print as REPL ie ‘3’
You don’t have to print to stdout, capture that and send back the string for getting repl-like output about results of your expressions. The repr function for example returns a string that should be similar to what the repl prints, you could just call that on the resulting value.