首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >"std::cout“在Android-ndk中可用吗?

"std::cout“在Android-ndk中可用吗?
EN

Stack Overflow用户
提问于 2012-01-15 13:59:59
回答 4查看 22.8K关注 0票数 44

在Android中,我们可以使用"__android_log_write“、"__android_log_print”、.等输出消息到"LogCat“窗口。如果我使用"std::cout“输出一些字符串,怎么样?例如。

代码语言:javascript
复制
std::cout << "some strings" << std::endl;

字符串会在哪里发送。

看起来Android没有控制台应用程序,上面的字符串可能不会发送。我是否可以将"stdout“重定向到一个文件,以便将字符串发送到"std::cout”相当于记录消息?

EN

回答 4

Stack Overflow用户

回答已采纳

发布于 2012-01-15 14:11:43

根据Android文档,stdout & stderr输出到/dev/null。您可以使用Android调试桥来实现您想要的结果。

默认情况下,Android系统将stdout和stderr (System.out和System.err)输出发送到/dev/null。在运行Dalvik VM的进程中,可以让系统将输出的副本写入日志文件。在本例中,系统使用带有优先级I的日志标记stdout和stderr将消息写入日志。要以这种方式路由输出,请停止运行的仿真器/设备实例,然后使用shell命令setprop启用输出的重定向。你是怎么做到的:

代码语言:javascript
复制
$ adb shell stop
$ adb shell setprop log.redirect-stdio true
$ adb shell start

系统保留此设置,直到终止模拟器/设备实例为止。若要将此设置用作模拟器/设备实例的默认设置,可以向设备上的/data/local.port添加一个条目。

票数 31
EN

Stack Overflow用户

发布于 2012-01-15 14:13:00

您可以创建一个从std::streambuf派生的类,它使用特定于Android的函数发送生成的字符序列。不过,我不知道std::cout的默认实现在哪里会在安卓上发送字符。基本上,这个看起来是这样的:

代码语言:javascript
复制
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];
};

要实际设置std::cout以写入此流缓冲区,您可以在main()函数中执行如下操作:

代码语言:javascript
复制
int main() {
    std::cout.rdbuf(new androidbuf);
    ...
}

这会为一个androidbuf流创建一个内存泄漏,但这在某种程度上是有意的:该流可能在main()退出后写入,并且在std::cout被销毁时被刷新。如果您不想这样做,您可以恢复std::cout的原始流缓冲区,或者将其设置为null并从rdbuf()删除返回。

代码语言:javascript
复制
   // avoid a one-time resource leak but don't get output afterwards:
   delete std::cout.rdbuf(0);
票数 40
EN

Stack Overflow用户

发布于 2016-08-04 03:56:50

另一种选择:

代码语言:javascript
复制
#include <sstream>

class MyStream
{
private:
   std::stringstream m_ss;
   int m_logLevel;
public:

   MyStream(int Xi_logLevel)
   {
      m_logLevel = Xi_logLevel;
   };
   ~MyStream()
   {
      __android_log_print(m_logLevel,LOG_TAG,"%s", m_ss.str().c_str());
   }

   template<typename T> MyStream& operator<<(T const& Xi_val)
   {
      m_ss << Xi_val;
      return *this;
   }
};

#define MY_LOG(LOG_LEVEL) MyStream(ANDROID_LOG_##LOG_LEVEL) << __FUNCTION__ << ":" << __LINE__ << " : "

的优点:

(1)即时打印讯息。

缺点:

(1)必须更改代码(std::cout -> MY_LOG(X))。

(2)每一次打印都会产生一个物体并将其销毁。

(* 这个答案以这个答案为基础)

票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/8870174

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档