Is “std::cout” usable in Android-ndk

前端 未结 4 1492
-上瘾入骨i
-上瘾入骨i 2020-12-02 18:31

In Android-ndk, we could use \"__android_log_write\", \"__android_log_print\", ... etc to output messages to the \"LogCat\" window. How about if I use \"std::cout\" to outpu

4条回答
  •  误落风尘
    2020-12-02 18:46

    You can create a class derived from std::streambuf which uses the Android specific functions to send the produced sequence of characters. I don't know where the default implementation of std::cout sends characters on Android, however. Basically, this would look something like this:

    class androidbuf : public std::streambuf {
    public:
        enum { bufsize = 128 }; // ... or some other suitable buffer size
        androidbuf() { this->setp(buffer, buffer + bufsize - 1); }
    
    private:
        int overflow(int c)
        {
            if (c == traits_type::eof()) {
                *this->pptr() = traits_type::to_char_type(c);
                this->sbumpc();
            }
            return this->sync()? traits_type::eof(): traits_type::not_eof(c);
        }
    
        int sync()
        {
            int rc = 0;
            if (this->pbase() != this->pptr()) {
                char writebuf[bufsize+1];
                memcpy(writebuf, this->pbase(), this->pptr() - this->pbase());
                writebuf[this->pptr() - this->pbase()] = '\0';
    
                rc = __android_log_write(ANDROID_LOG_INFO, "std", writebuf) > 0;
                this->setp(buffer, buffer + bufsize - 1);
            }
            return rc;
        }
    
        char buffer[bufsize];
    };
    

    To actually set up std::cout to write to this stream buffer, you would do something like this in your main() function:

    int main() {
        std::cout.rdbuf(new androidbuf);
        ...
    }
    

    This create a memory leak for the one androidbuf stream which is, however, somewhat intentional: the stream may be written to after main() is exited and it is flushed when when std::cout gets destroyed. If you don't want this, you could either restore std::cout's original stream buffer or set it to null and delete the return from rdbuf():

       // avoid a one-time resource leak but don't get output afterwards:
       delete std::cout.rdbuf(0);
    

提交回复
热议问题