JNI控制台输出的顺序

在Java中使用调用c++程序时,遇到了标准输出输出顺序的一个问题。

假设有Java代码如下

public class Main {

    public static void main(String[] args) {
        System.out.println("Hello World!");
        System.loadLibrary("JNITest");
        HelloCpp a = new HelloCpp();
        a.hellocpp();
    }
}

public class HelloCpp {
    public native void hellocpp();
}

C++代码如下

JNIEXPORT void JNICALL Java_HelloCpp_hellocpp(JNIEnv *, jobject)
{
	printf("hello from cpp\n");
}

上述代码成功编译执行后的控制台输出为

Hello World!

Hello Java!

hello from cpp

这样的内容,显然不是我们所预期的。具体来说就是即使C++的输出在执行的时候在Java之前,Java的也会先输出,C++的会后输出。百度之后找到了这样一个帖子

https://bbs.csdn.net/topics/391939316

有人回答是

如我们上面谈到的,这里涉及到跨进程通信,这个过程是耗时的,所以可能存在消息延迟。

就结论而言,该说法是错的。在得到结论之前我们来更换一下代码试试。C++的改成如下代码:

JNIEXPORT void JNICALL Java_HelloCpp_hellocpp(JNIEnv *, jobject)
{
	cout << "hello from cpp" << endl;
}

我们会得到输出

Hello World!

hello from cpp

Hello Java!

看吧,如果如帖子中的回答那样,这里不应该出现这样的结果的。几乎所有C++的书上都会写std::endl和"\n"的区别,那就是刷新缓冲区。因此使用如下代码是可以得到同样的结果的

JNIEXPORT void JNICALL Java_HelloCpp_hellocpp(JNIEnv *, jobject)
{
	printf("hello from cpp\n");
	cout.flush();
}
这就说明了,JNI的C++程序的标准输出拥有自己独立的缓冲区,Java代码拥有自己的缓冲区,它们互不影响,每次刷新缓冲区,C++才能将标准输出送到Java的控制台,二者输出顺序与进程通信什么的没有丝毫关系,仅仅是因为缓冲区的问题。
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值