通过 JNI 接口共享输出流

我正在编写一个 Java 应用程序,该应用程序通过 JNI 接口使用C++库。C++库创建类型的对象,这些对象通过JNI适当地传递到Java。Foo

假设库具有输出函数

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

我有一个Java。如何从 Java 调用,以便输出显示在 ?有没有办法强制在 JNI 层中将 a 强制到 a?我是否可以在JNI层的缓冲区中捕获输出,然后将其复制到?OutputStream outFoo::printoutOutputStreamstd::ostreamout


答案 1

我会实现一个C++ ostream,它缓冲写入(最多一些设置的大小),然后通过JNI将这些写入刷新到java OutputStream。

在 Java 端,您可以使用常规的 OutputStream 实例,也可以实现缓冲区块(实质上是 byte[])的排队,以避免线程之间任何可能的锁定争用。实际输出流仅由另一个线程上的任务使用,该线程从队列中提取块并将其写入 OutpuStream。我不能说这是否有必要或没有达到这个细节水平 - 你可能会发现直接从JNI写入输出流是有效的。

我不与JNI分享其他海报的担忧,也不认为使用JNI有任何问题。当然,你的维护者必须知道他们的东西,但仅此而已,Java/C++层的复杂性可以通过文档、示例和测试用例来管理。过去,我已经实现了一个Java<>COM桥接器,具有相当健谈的界面 - 在性能,线程或维护方面没有问题。

给定一个完全自由的选择,就不会有JNI,但对我来说,它通过使原本不兼容的系统紧密集成成为可能,节省了一天的时间。


答案 2

我已经在我的博客上发表了一篇文章,详细介绍了我最近遇到同样问题的经历。通常,您希望避免尝试以任何语言将输入或输出流连接到客户端,因为它暗示了线程。您可以使用回调以增量方式传递数据。


推荐