web-dev-qa-db-ja.com

C ++とJavaプロセス間の共有メモリ

私の目的は、C++プロセスからJavaプロセスにデータを渡し、結果を受け取ることです。

名前付きパイプを介してこれを実現しましたが、アクセスが高速であると想定して、データを渡したりコピーしたりするのではなく、データを共有したいと思います。

当初、Javaで読み書きできる共有セグメントをC++で作成することを考えていましたが、安全はもちろん、JNIを介してこれが可能かどうかはわかりません。

JavaでByteBuffer.allocateDirectを使用してメモリを割り当て、GetDirectBufferAddressを使用してC++のアドレスにアクセスすることは可能だと思いますが、正しければ、これはJNI内のネイティブ呼び出し用であり、私のC++プロセスでこのアドレスを取得しませんか?

失われました。

よろしくお願いします。

17
Brent Campbell

たとえば CreateFileMapping (Windows)またはshmget(Unix)を使用してメモリを共有している場合、必要なのはJava側。次に、直接を使用して共有メモリにアクセスする ByteBuffer を作成できます。 NewDirectByteBuffer このように:

JNIEXPORT jobject JNICALL Java_getSharedBuffer(JNIEnv* env, jobject caller) {
    void* myBuffer;
    int bufferLength;

次に、共有メモリへのポインタを取得する必要があります。 Windowsでは、次のようなものを使用します。

    bufferLength = 1024; // assuming your buffer is 1024 bytes big
    HANDLE mem = OpenFileMapping(FILE_MAP_READ, // assuming you only want to read
           false, "MyBuffer"); // assuming your file mapping is called "MyBuffer"
    myBuffer = MapViewOfFile(mem, FILE_MAP_READ, 0, 0, 0);
    // don't forget to do UnmapViewOfFile when you're finished

これで、この共有メモリに支えられたByteBufferを作成できます。

    // put it into a ByteBuffer so the Java code can use it
    return env->NewDirectByteBuffer(myBuffer, bufferLength);
}
13
main--

MQ の使用を検討しましたか? JavaC++ の両方をサポートし、より信頼性が高くなります。 Javaで共有メモリを実行する場合は、JNI経由で行う必要があると思います。前回調べたとき、他の方法はありませんでした。

これは、そのルートに移動する場合は、 [〜#〜] jni [〜#〜] を介して実行する必要があることを示しています。私が見つけた解決策はWindows固有のものですが、あなたには当てはまらないかもしれません。

4
Shafik Yaghmour