Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

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?

like image 683
rmcp Avatar asked Dec 10 '25 09:12

rmcp


1 Answers

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.

like image 103
technomage Avatar answered Dec 11 '25 23:12

technomage



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!