17

JNI インターフェイスを介して C++ ライブラリを使用する Java アプリケーションを作成しています。C++ ライブラリは、タイプ のオブジェクトを作成します。これらのオブジェクトはFoo、JNI を介して Java に適切に渡されます。

ライブラリに出力関数があるとします。

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

そして私は Java を持っていますOutputStream outFoo::print出力が表示されるようにJavaから呼び出すにはどうすればよいoutですか? JNIレイヤーでOutputStreamaを強制する方法はありますか? std::ostream出力を JNI レイヤーのバッファーにキャプチャしてからコピーすることはできoutますか?

4

3 に答える 3

6

JNIを介してJava OutputStreamに書き込みをフラッシュする前に、書き込みを(一定のサイズまで)バッファリングするC++ ostreamを実装します。

Java 側では、通常の OutputStream インスタンスを使用するか、バッファ ブロック (基本的には byte[]) のキューイングを実装して、スレッド間のロック競合を回避することができます。実際の出力ストリームは、キューからブロックをプルして OutpuStream に書き込む別のスレッド上のタスクによってのみ使用されます。このレベルの詳細では、これが必要かどうかはわかりません。JNI の動作から出力ストリームに直接書き込みを行うことがわかるかもしれません。

私は他の投稿者の懸念を JNI と共有しておらず、これに JNI を使用しても問題はないと考えています。確かに、メンテナーは自分たちのことを知っている必要がありますが、それだけで、Java/C++ レイヤーの複雑さは、ドキュメント、例、およびテスト ケースで管理できます。過去に、私は Java<>COM ブリッジをかなりおしゃべりなインターフェースで実装しました - パフォーマンス、スレッド、またはメンテナンスに問題はありません。

完全に自由な選択があれば、JNI はありませんが、私にとっては、互換性のないシステムの緊密な統合を可能にすることで、1 日を節約できました。

于 2010-04-27T17:32:53.787 に答える
3

このまったく同じ問題に関する最近の経験を詳述した記事をブログに投稿しました。一般に、入力ストリームまたは出力ストリームを任意の言語のクライアントに接続しようとすることは、スレッドを意味するため避けたいと考えています。コールバックを使用して、データを段階的に配信できます。

于 2010-04-23T01:52:16.493 に答える
0

JavaからFoo::printを呼び出して、出力が出力に表示されるようにするにはどうすればよいですか?

概念的には、Foo :: print(...)を既存のJava OutputStreamインスタンスに書き込む方法は、出力を行うために実際にJavaへのコールバックを行うC ++ std::ostream実装を作成することです。

それは可能に聞こえますが、私はコードを書いたり維持したりしたくありません。実行時に、Java-> C ++-> Javaからの呼び出しがあり、JVMをランダムにクラッシュさせるミスを犯す機会がたくさんあります。

OutputStreamをJNIレイヤーのstd::ostreamに強制変換する方法はありますか?

AFAIK番号

JNIレイヤーのバッファーに出力をキャプチャして、それをコピーして出力することはできますか?

おおざっぱに言ってこういう意味ですか?

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

あなたはおそらくそのような仕事をすることができます...次の風で良い日に。

しかし、JNI全体でますます複雑になることをやろうとするのではなく、C++コードを排除することを本当に目指すべきだと思います。IMO、JNIは最後の手段としてのみ使用する必要があり、Javaでの再コーディングを回避するためのショートカットではありません。

于 2009-09-16T22:49:26.553 に答える