通过JNI接口共享输出流

 2023-01-19    375  

问题描述

我正在编写通过JNI接口使用C ++库的Java应用程序. C ++库会创建类型Foo的对象,这些对象通过JNI正式传递到JAVA.

假设库具有输出函数

通过JNI接口共享输出流

void Foo::print(std::ostream &os)

我有一个Java OutputStream out.如何从Java调用Foo::print,以便输出出现在out上?有什么方法可以将OutputStream胁迫到JNI层中的std::ostream?我可以在缓冲区中捕获JNI层的输出,然后将其复制到out?

推荐答案

我将实现一个C ++的Ostream,该C ++ Ostream在通过JNI将其写入JNI之前,然后将其刷新到Java UppotStream.

在Java侧,您可以使用常规的OutputStream实例,也可以实现缓冲区块的排队(本质上是字节[]),以避免线程之间的任何可能的锁定争论.实际输出流仅由另一个线程上的任务使用,该线程将块从队列拉出并将其写入外部.我不能说这是否在此细节上是否有必要 – 您很可能会直接找到JNI Works的输出流的写作.

我不与JNI共享其他海报的关注,也不会看到使用JNI的任何问题.当然,您的维护者必须知道他们的知识,但这就是关于这一点,可以通过文档,示例和测试用例来管理Java/C ++层的复杂性.过去,我已经实现了一个具有相当健谈的接口的Java com桥 – 性能,线程或维护毫无问题.

给出了一个完全免费的选择,没有JNI,但是对我来说,它通过使原本不相容的系统的紧密整合而节省了一天.

其他推荐答案

我已经发布了在我的博客上撰写详细介绍了我最近的同样问题的经历.通常,您要避免尝试将输入或输出流连接到任何语言的客户端,这意味着线程.您可以使用回调逐步传递数据.

其他推荐答案

我如何调用foo ::从java打印
因此,输出出现了?

从概念上讲,获取foo :: print(…)写入现有Java UptumStream实例的方法是编写C ++ STD :: Ostream实现,该实现实际上是在Java中进行回调以进行输出.

听起来可能是可能的,但是我不想编写/维护代码.在运行时,您将接到Java-> C ++ – > Java的电话,并且有很多机会会随机崩溃您的JVM.

有什么办法胁迫
输出到std :: Ostream在
jni层?

afaik no.

我可以在缓冲区中捕获输出
JNI层,然后将其复制到
出去?

您的意思是大致像这样吗?

MyJNIThing m = ...
    int myOstream = m.createMemoryBackedOStream(...); // native method
    ...
    m.someMethodWrapper(... myOStream); // native method
    ...
    byte[] data = m.getCapturedData(myOStream); // native method
    out.write(data);

您可能可以使像这样的工作…在随后的风中度过美好的一天.

但我认为您确实应该打算消除C ++代码,而不是试图在JNI中做越来越复杂的事情. IMO,JNI只能用作最后的手段,而不应用捷径来避免在Java中重新编码.

以上所述是小编给大家介绍的通过JNI接口共享输出流,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对77isp云服务器技术网的支持!

原文链接:https://77isp.com/post/25765.html

=========================================

https://77isp.com/ 为 “云服务器技术网” 唯一官方服务平台,请勿相信其他任何渠道。