2015-09-07 3 views
0

Как я могу прочитать раздел разделяемой памяти, например «Глобальный \ something_something» в java, который был создан и обновлен программой C#/C++? Я нашел несколько учебников, но они либо работают с «реальными файлами», либо имеют некоторые другие дополнительные материалы. Я знаю, что я должен делать собственные вызовы через jna, например, в windows api и использовать что-то вроде функции openFileMapping.Чтение общей памяти из C++/C# программы в java

Есть ли учебные пособия, которые я пропустил, или кто-нибудь может дать мне пример кода примера? Является ли использование jna или jni единственным способом для такого рода вещей в java?

+0

Возможно, вы совершенно правы и должны руководствоваться решением на основе JNI, реализованным на каком-то низкоуровневом языке (C?). –

+0

Использование файла с отображением памяти - единственный способ сделать это на Java без дополнительного собственного кода. Однако, пока вы не вызываете синхронизацию широко, нет никакой разницы между «реальным» временным файлом и любыми другими способами создания разделяемой памяти. – Holger

ответ

1

Если вы можете получить указатель на ячейку памяти, вы можете использовать методы Pointer JNA для доступа к памяти. В качестве альтернативы вы можете создать direct NIO Buffer, что облегчает обмен памяти между Java и native.

Любой из этих методов должен работать одинаково хорошо для обмена памятью.

// Use JNA-allocated non-Java heap memory 
Memory m = new Memory(size); 
myNativeLib.useSharedMemory(m); 
// Use JVM-allocated non-Java heap memory 
Buffer b = ByteBuffer.allocateDirect(size); 
myNativeLib.useSharedMemory(b); 
// Use native-allocated memory 
Pointer p = myNativeLib.getSharedPointer(); 

Если вы хотите поделиться более доступной физической памяти, то вы бы лучше использовать file-based mapping.

EDIT

адресация конкретный вопрос о доступе к блок Окнах Named Shared Memory, вы должны понять, как получить к нему доступ через W32 API, а затем получить доступ к этим API, через ЮНА (или JNI, если вы предпочитаете).

С MS Docs:

HANDLE hMapFile; 
    LPCTSTR pBuf; 

    hMapFile = OpenFileMapping(
        FILE_MAP_ALL_ACCESS, // read/write access 
        FALSE,     // do not inherit the name 
        szName);    // name of mapping object 

    if (hMapFile == NULL) 
    { 
     _tprintf(TEXT("Could not open file mapping object (%d).\n"), 
      GetLastError()); 
     return 1; 
    } 

    pBuf = (LPTSTR) MapViewOfFile(hMapFile, // handle to map object 
       FILE_MAP_ALL_ACCESS, // read/write permission 
       0, 
       0, 
       BUF_SIZE); 

    if (pBuf == NULL) 
    { 
     _tprintf(TEXT("Could not map view of file (%d).\n"), 
      GetLastError()); 

     CloseHandle(hMapFile); 

     return 1; 
    } 

Это простой вопрос, чтобы сопоставить эти функции в ЮНА для использования в Java:

import com.sun.jna.platform.win32.Kernel32; 
import com.sun.jna.Native; 

public interface MyKernel32 extends Kernel32 { 
    int FILE_MAP_ALL_ACCESS = // look it up 
    MyKernel32 INSTANCE = (MyKernel32)Native.loadLibrary(MyKernel32.class, W32APIOptions.DEFAULT_OPTIONS); 
    HANDLE OpenFileMapping(int dwDesiredAccess, boolean bInheritHandle, String lpName); 
} 

Обратите внимание, что ЮНА-х Kernel32platform.jar) уже включает в себя отображение для MapViewOfFile, который возвращает Pointer. Используя это возвращаемое значение, вы можете читать и записывать в разделяемую память на контент вашего сердца.

+0

Спасибо за ваш ответ, но я все еще немного потерян. У меня есть приложение A, к которому у меня нет источника, который создает раздел разделяемой памяти под названием «Global \ application_A» и обновляет данные там каждую секунду (это не так много данных, всего несколько килобайт). Теперь я хочу создать приложение B в java, которое читает эту общую память A для ее печати на консоли. Ему не нужен доступ на запись, только чтение. – rmcp

+0

Пожалуйста, обратитесь к деталям определения раздела «разделяемая память». Возможно, вы имеете в виду [это] (https://msdn.microsoft.com/en-us/library/windows/desktop/aa366551 (v = vs.85) .aspx)? – technomage

+0

Да, я так думаю. Когда я смотрю на процесс с помощью sysinternal explorer процесса и отображает дескрипторы, «Global \ application_A» появляется как «Раздел», и в его свойствах говорится «Файл с отображением памяти в области подкачки под псевдонимом» в качестве описания. Я также вижу адрес там вроде «0xFFFFC00203422520», хотя я не думаю, что это помогает. – rmcp

Смежные вопросы