Reading shared memory from c++/c# program in java

点点圈 提交于 2019-12-24 23:12:37

问题


How can I read a shared memory section like "Global\something_something" in java that was created and is updated by a c#/c++ program? I found some tutorials, but they either work with "real files" or have some other additional stuff. I know that I have to make native calls via jna, for example, to the windows api and use something like the openFileMapping function.

Are there tutorials I have missed or could someone give me a bit of example code? Is using jna or jni the only way to that sort of thing in java?


回答1:


If you can obtain a pointer to the memory location, you can use JNA's Pointer methods to access the memory. Alternatively you can create a direct NIO Buffer, which facilitates sharing memory between Java and native.

Any one of these methods should work equally well for sharing memory.

// 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();

If you want to share more than available physical memory, then you'd be better off using a file-based mapping.

EDIT

Addressing the specific question of accessing a Windows block of Named Shared Memory, you need to understand how to access it via w32 APIs and then access those APIs via JNA (or JNI, if you prefer).

From the 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;
   }

It's a straightforward matter to map these functions into JNA for use in 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);
}

Note that JNA's Kernel32 (in platform.jar) already includes a mapping for MapViewOfFile, which returns a Pointer. Using that returned value, you can read and write to the shared memory to your heart's content.



来源:https://stackoverflow.com/questions/32440527/reading-shared-memory-from-c-c-program-in-java

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!