Hi all,
I have been working on an R interface package to a shared library written
in C++. It works almost perfectly, but the output to std::cout is not shown
on R console (on Linux). Of course Rcpp::Rcout should be used instead of
std::cout. But in this case I want to let the shared library be pure C++.
So I tried switching the stream buffers in the Rcpp side:
```
Rcpp::CharacterVector run(const std::vector<std::string>& args) {
std::streambuf* obuf = std::cout.rdbuf(Rcpp::Rcout.rdbuf());
mylib::Simulation simulation(args);
simulation.run(); // std::cout is used in here
std::cout.rdbuf(obuf);
return "something";
}
```
It (seemingly) works! But now `devtools::check()` produces 1 note:
```
? checking compiled code ... NOTE
File ?mylib/libs/mylib.so?:
Found ?__ZNSt3__14coutE?, possibly from ?std::cout? (C++)
Object: ?run.o?
Compiled code should not call entry points which might terminate R nor
write to stdout/stderr instead of to the console, nor use Fortran I/O
nor system RNGs.
```
Can I suppress this note? or should I just ignore it? any other good
solution?
Thanks,
Watal M. Iwasaki
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.r-forge.r-project.org/pipermail/rcpp-devel/attachments/20181026/edd5272c/attachment.html>
[Rcpp-devel] How to handle std::cout/std::cerr in shared libraries
9 messages · Dirk Eddelbuettel, Watal M. Iwasaki
On 26 October 2018 at 16:31, Watal M. Iwasaki wrote:
| I have been working on an R interface package to a shared library written
| in C++. It works almost perfectly, but the output to std::cout is not shown
| on R console (on Linux). Of course Rcpp::Rcout should be used instead of
| std::cout. But in this case I want to let the shared library be pure C++.
| So I tried switching the stream buffers in the Rcpp side:
| ```
| Rcpp::CharacterVector run(const std::vector<std::string>& args) {
| std::streambuf* obuf = std::cout.rdbuf(Rcpp::Rcout.rdbuf());
| mylib::Simulation simulation(args);
| simulation.run(); // std::cout is used in here
| std::cout.rdbuf(obuf);
| return "something";
| }
| ```
|
| It (seemingly) works! But now `devtools::check()` produces 1 note:
| ```
| ? checking compiled code ... NOTE
| File ?mylib/libs/mylib.so?:
| Found ?__ZNSt3__14coutE?, possibly from ?std::cout? (C++)
| Object: ?run.o?
|
| Compiled code should not call entry points which might terminate R nor
| write to stdout/stderr instead of to the console, nor use Fortran I/O
| nor system RNGs.
| ```
|
| Can I suppress this note? or should I just ignore it? any other good
| solution?
You need to change it. There is no automatic fix.
[ Longer answer: See eg what we do in RcppArmadillo where we #define a device
which for builds that we do from R fills in Rcpp::Rcout and otherwise
defaults to std::cout. But the essence is the same: _You_ need to change
that library code to conform. Or keep the library outside the R package but
then you have an external dependency. ]
Dirk
http://dirk.eddelbuettel.com | @eddelbuettel | edd at debian.org
Dear Dirk, Thank you for the prompt response. Good to know there is no easy way. I have made up my mind to change the library code as you suggested. But I don't like preprocessor macro; therefore, the problem here was solved by moving/hiding `std::cout.rdbuf()` part into the library as a function that takes a streambuf pointer, and just calling it from Rcpp side. Now, output is properly sent to R console, R CMD check complains nothing, and the library still remains free from R/Rcpp code. Thanks again. Best, Watal
On Fri, Oct 26, 2018 at 9:29 PM Dirk Eddelbuettel <edd at debian.org> wrote:
On 26 October 2018 at 16:31, Watal M. Iwasaki wrote:
| I have been working on an R interface package to a shared library written
| in C++. It works almost perfectly, but the output to std::cout is not
shown
| on R console (on Linux). Of course Rcpp::Rcout should be used instead of
| std::cout. But in this case I want to let the shared library be pure C++.
| So I tried switching the stream buffers in the Rcpp side:
| ```
| Rcpp::CharacterVector run(const std::vector<std::string>& args) {
| std::streambuf* obuf = std::cout.rdbuf(Rcpp::Rcout.rdbuf());
| mylib::Simulation simulation(args);
| simulation.run(); // std::cout is used in here
| std::cout.rdbuf(obuf);
| return "something";
| }
| ```
|
| It (seemingly) works! But now `devtools::check()` produces 1 note:
| ```
| ? checking compiled code ... NOTE
| File ?mylib/libs/mylib.so?:
| Found ?__ZNSt3__14coutE?, possibly from ?std::cout? (C++)
| Object: ?run.o?
|
| Compiled code should not call entry points which might terminate R nor
| write to stdout/stderr instead of to the console, nor use Fortran I/O
| nor system RNGs.
| ```
|
| Can I suppress this note? or should I just ignore it? any other good
| solution?
You need to change it. There is no automatic fix.
[ Longer answer: See eg what we do in RcppArmadillo where we #define a
device
which for builds that we do from R fills in Rcpp::Rcout and otherwise
defaults to std::cout. But the essence is the same: _You_ need to change
that library code to conform. Or keep the library outside the R package
but
then you have an external dependency. ]
Dirk
--
http://dirk.eddelbuettel.com | @eddelbuettel | edd at debian.org
Watal M. Iwasaki / ?? ? SOKENDAI, The Graduate University for Advanced Studies, Hayama, Kanagawa 240-0193, Japan +81-46-858-1576 https://heavywatal.github.io/ -------------- next part -------------- An HTML attachment was scrubbed... URL: <http://lists.r-forge.r-project.org/pipermail/rcpp-devel/attachments/20181026/c8e44062/attachment.html>
On 26 October 2018 at 22:03, Watal M. Iwasaki wrote:
| Dear Dirk, | | Thank you for the prompt response. Good to know there is no easy way. I | have made up my mind to change the library code as you suggested. But I | don't like preprocessor macro; therefore, the problem here was solved by | moving/hiding `std::cout.rdbuf()` part into the library as a function that | takes a streambuf pointer, and just calling it from Rcpp side. Now, output | is properly sent to R console, R CMD check complains nothing, and the | library still remains free from R/Rcpp code. Thanks again. Nicely done. We could do with a more general solution to this. If you have ideas ... Dirk
http://dirk.eddelbuettel.com | @eddelbuettel | edd at debian.org
Dear Dirk, Is it possible for Rcpp to do some pre-execution hook before user code? For example, if Rcpp system can hijack the std::cout buffer by executing `std::cout.rdbuf(Rcpp::Rcout.rdbuf())` automatically, then Rcpp users (and external libraries) no longer have to care about Rcout, and can just stick to std::cout. Best, Watal
On Fri, Oct 26, 2018 at 10:12 PM Dirk Eddelbuettel <edd at debian.org> wrote:
On 26 October 2018 at 22:03, Watal M. Iwasaki wrote: | Dear Dirk, | | Thank you for the prompt response. Good to know there is no easy way. I | have made up my mind to change the library code as you suggested. But I | don't like preprocessor macro; therefore, the problem here was solved by | moving/hiding `std::cout.rdbuf()` part into the library as a function that | takes a streambuf pointer, and just calling it from Rcpp side. Now, output | is properly sent to R console, R CMD check complains nothing, and the | library still remains free from R/Rcpp code. Thanks again. Nicely done. We could do with a more general solution to this. If you have ideas ... Dirk -- http://dirk.eddelbuettel.com | @eddelbuettel | edd at debian.org
Watal M. Iwasaki / ?? ? SOKENDAI, The Graduate University for Advanced Studies, Hayama, Kanagawa 240-0193, Japan +81-46-858-1576 https://heavywatal.github.io/ -------------- next part -------------- An HTML attachment was scrubbed... URL: <http://lists.r-forge.r-project.org/pipermail/rcpp-devel/attachments/20181026/c4d05420/attachment.html>
Hi Watal,
On 26 October 2018 at 23:36, Watal M. Iwasaki wrote:
| Is it possible for Rcpp to do some pre-execution hook before user code? For | example, if Rcpp system can hijack the std::cout buffer by executing | `std::cout.rdbuf(Rcpp::Rcout.rdbuf())` automatically, then Rcpp users (and | external libraries) no longer have to care about Rcout, and can just stick | to std::cout. Sorry, but we need the opposite (which is what Rcpp::Rcout does): we need to get what _would otherwise go to std::cout_ and feed it to Rcpp::Rcout which then hands it to R's buffered i/o. That is the whole underlying reason -- see the as always very detailed "Writing R Extensions" manual for a bit more. Automating that (ie replacing std::cout by Rcpp::Rcout) is what is needed. Dirk
http://dirk.eddelbuettel.com | @eddelbuettel | edd at debian.org
Dear Dirk,
Sorry for my poor explanation. I have read
`inst/include/Rcpp/iostream/Rstreambuf.h` and think I understand the role
of Rcpp::Rcout, but failed to explain my point. By "users [...] can just
stick to std::cout", I did not mean allowing users to write to stdout via
std::cout. It is about changing the destination of std::cout from stdout to
R's i/o. The following code hopefully explains better:
```
// [[Rcpp::export]]
void example_function() {
// Normal state
std::cout << "to stdout; BAD\n";
Rcpp::Rcout << "to R's i/o\n";
// Ideal state
std::streambuf* stdoutbuf = std::cout.rdbuf(Rcpp::Rcout.rdbuf());
std::cout << "to R's i/o via Rcpp::Rcout.buf; GOOD\n"
Rcpp::Rcout << "to R's i/o\n";
// Restore original state
std::cout.rdbuf(stdoutbuf);
std::cout << "to stdout; BAD\n";
Rcpp::Rcout << "to R's i/o\n";
}
```
In other words, we don't have to replace std::cout with Rcpp::Rcout. We
only have to change its buffer.
Thanks,
Watal
On Sat, Oct 27, 2018 at 12:09 AM Dirk Eddelbuettel <edd at debian.org> wrote:
Hi Watal, On 26 October 2018 at 23:36, Watal M. Iwasaki wrote: | Is it possible for Rcpp to do some pre-execution hook before user code? For | example, if Rcpp system can hijack the std::cout buffer by executing | `std::cout.rdbuf(Rcpp::Rcout.rdbuf())` automatically, then Rcpp users (and | external libraries) no longer have to care about Rcout, and can just stick | to std::cout. Sorry, but we need the opposite (which is what Rcpp::Rcout does): we need to get what _would otherwise go to std::cout_ and feed it to Rcpp::Rcout which then hands it to R's buffered i/o. That is the whole underlying reason -- see the as always very detailed "Writing R Extensions" manual for a bit more. Automating that (ie replacing std::cout by Rcpp::Rcout) is what is needed. Dirk -- http://dirk.eddelbuettel.com | @eddelbuettel | edd at debian.org
Watal M. Iwasaki / ?? ? SOKENDAI, The Graduate University for Advanced Studies, Hayama, Kanagawa 240-0193, Japan +81-46-858-1576 https://heavywatal.github.io/ -------------- next part -------------- An HTML attachment was scrubbed... URL: <http://lists.r-forge.r-project.org/pipermail/rcpp-devel/attachments/20181027/b4f57672/attachment.html>
Hi Watal, Thanks for being patient with me :)
On 27 October 2018 at 01:26, Watal M. Iwasaki wrote:
| Sorry for my poor explanation. I have read
| `inst/include/Rcpp/iostream/Rstreambuf.h` and think I understand the role
| of Rcpp::Rcout, but failed to explain my point. By "users [...] can just
| stick to std::cout", I did not mean allowing users to write to stdout via
| std::cout. It is about changing the destination of std::cout from stdout to
| R's i/o. The following code hopefully explains better:
|
| ```
| // [[Rcpp::export]]
| void example_function() {
| // Normal state
| std::cout << "to stdout; BAD\n";
| Rcpp::Rcout << "to R's i/o\n";
|
| // Ideal state
| std::streambuf* stdoutbuf = std::cout.rdbuf(Rcpp::Rcout.rdbuf());
| std::cout << "to R's i/o via Rcpp::Rcout.buf; GOOD\n"
| Rcpp::Rcout << "to R's i/o\n";
|
| // Restore original state
| std::cout.rdbuf(stdoutbuf);
| std::cout << "to stdout; BAD\n";
| Rcpp::Rcout << "to R's i/o\n";
| }
| ```
|
| In other words, we don't have to replace std::cout with Rcpp::Rcout. We
| only have to change its buffer.
I like it! I think that may fix it.
It may not fix the detection by R CMD check, but if we can show that we do
the right thing maybe this can be adjusted (to also account for Rcpp and
whatever (hidden) macro we may use to provide this.
Dirk
http://dirk.eddelbuettel.com | @eddelbuettel | edd at debian.org
Yes, escaping from the check seems difficult. I have created a quick PR on this for further discussion. Watal
On Sat, Oct 27, 2018 at 2:13 AM Dirk Eddelbuettel <edd at debian.org> wrote:
Hi Watal,
Thanks for being patient with me :)
On 27 October 2018 at 01:26, Watal M. Iwasaki wrote:
| Sorry for my poor explanation. I have read
| `inst/include/Rcpp/iostream/Rstreambuf.h` and think I understand the role
| of Rcpp::Rcout, but failed to explain my point. By "users [...] can just
| stick to std::cout", I did not mean allowing users to write to stdout via
| std::cout. It is about changing the destination of std::cout from stdout
to
| R's i/o. The following code hopefully explains better:
|
| ```
| // [[Rcpp::export]]
| void example_function() {
| // Normal state
| std::cout << "to stdout; BAD\n";
| Rcpp::Rcout << "to R's i/o\n";
|
| // Ideal state
| std::streambuf* stdoutbuf = std::cout.rdbuf(Rcpp::Rcout.rdbuf());
| std::cout << "to R's i/o via Rcpp::Rcout.buf; GOOD\n"
| Rcpp::Rcout << "to R's i/o\n";
|
| // Restore original state
| std::cout.rdbuf(stdoutbuf);
| std::cout << "to stdout; BAD\n";
| Rcpp::Rcout << "to R's i/o\n";
| }
| ```
|
| In other words, we don't have to replace std::cout with Rcpp::Rcout. We
| only have to change its buffer.
I like it! I think that may fix it.
It may not fix the detection by R CMD check, but if we can show that we do
the right thing maybe this can be adjusted (to also account for Rcpp and
whatever (hidden) macro we may use to provide this.
Dirk
--
http://dirk.eddelbuettel.com | @eddelbuettel | edd at debian.org
Watal M. Iwasaki / ?? ? SOKENDAI, The Graduate University for Advanced Studies, Hayama, Kanagawa 240-0193, Japan +81-46-858-1576 https://heavywatal.github.io/ -------------- next part -------------- An HTML attachment was scrubbed... URL: <http://lists.r-forge.r-project.org/pipermail/rcpp-devel/attachments/20181027/58c2966f/attachment.html>