Общая память между процессами С++ и Java

Моя цель - передать данные из процесса С++ в процесс Java, а затем вернуть результат.

Я достиг этого через именованный канал, но я предпочел бы использовать данные, а не передавать или копировать их, предполагая, что доступ будет быстрее.

Вначале я думал о создании общего сегмента на С++, который мог писать и читать с помощью Java, но я не уверен, что это возможно через JNI, не говоря уже о безопасности.

Я полагаю, что в Java можно выделить память с помощью ByteBuffer.allocateDirect, а затем использовать GetDirectBufferAddress для доступа к адресу на С++, но если я прав, это для внутренних вызовов внутри JNI, и я не могу получить этот адрес в мой С++-процесс?

Проиграл.

Большое спасибо заранее.

Ответы

Ответ 1

Если у вас есть разделяемая память, например, 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);
}

Ответ 2

Считаете ли вы использование 0MQ, он поддерживает как Java и С++ и будет более надежным. Я думаю, что если вы хотите делать общую память в Java, это должно быть через JNI, в прошлый раз, когда я смотрел, не было другого способа сделать это.

Это показывает, что вам нужно сделать это через JNI, если вы идете по этому маршруту. Хотя решения, которые я нашел, являются специфичными для Windows, которые могут не относиться к вам.