Общая память между процессами С++ и 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, которые могут не относиться к вам.