Chr*_*way 13 c++ java java-native-interface iostream outputstream
我正在编写一个通过JNI接口使用C++库的Java应用程序.C++库创建了类型的对象Foo,这些对象通过JNI传递给Java.
假设库具有输出功能
void Foo::print(std::ostream &os)
Run Code Online (Sandbox Code Playgroud)
我有一个Java OutputStream out.如何Foo::print从Java 调用以便输出显示out?有什么办法来要挟OutputStream到std::ostream在JNI层?我可以在缓冲区中捕获JNI层的输出,然后将其复制到out?
我将实现一个C++ ostream来缓冲写入(最多一些设置大小),然后通过JNI将这些写入刷新到java OutputStream.
在java方面,您可以使用常规的OutputStream实例,也可以实现缓冲区块的排队(实际上是byte []),以避免线程之间可能存在的锁定争用.实际输出流仅由另一个线程上的任务使用,该线程从队列中提取块并将它们写入OutpuStream.我不能说在这个细节层次上是否有必要 - 你可能会发现直接写入JNI工作的输出流.
我没有与JNI分享其他海报问题,也没有看到使用JNI的任何问题.当然,你的维护者必须知道他们的东西,但就是这样,Java/C++层的复杂性可以通过文档,示例和测试用例来管理.在过去,我已经实现了一个Java <> COM桥接器,界面非常繁琐 - 性能,线程或维护都没有问题.
鉴于完全自由的选择,没有JNI,但对我而言,它通过使其他不兼容系统的紧密集成成为可能来节省时间.
如何从 Java 调用 Foo::print 以便输出出现在 out 上?
从概念上讲,让 Foo::print(...) 写入现有 Java OutputStream 实例的方法是编写一个 C++ std::ostream 实现,该实现实际上对 Java 进行回调以进行输出。
这听起来可能,但我不想编写/维护代码。在运行时,您将有来自 Java -> C++ -> Java 的调用,并且有很多机会犯错误,从而导致 JVM 随机崩溃。
有什么方法可以将 OutputStream 强制转换为 JNI 层中的 std::ostream 吗?
据我所知没有。
我可以捕获 JNI 层缓冲区中的输出,然后将其复制到 out 中吗?
你的意思大概是这样的吗?
MyJNIThing m = ...
int myOstream = m.createMemoryBackedOStream(...); // native method
...
m.someMethodWrapper(... myOStream); // native method
...
byte[] data = m.getCapturedData(myOStream); // native method
out.write(data);
Run Code Online (Sandbox Code Playgroud)
你也许可以做这样的事情……在有风的好天气里。
但我认为您真正的目标应该是消除 C++ 代码,而不是尝试通过 JNI 做越来越复杂的事情。在我看来,JNI 只能作为最后的手段,而不是避免用 Java 重新编码的捷径。