从java中的c ++ / c#程序读取共享内存

时间:2015-09-07 14:02:22

标签: java c++ java-native-interface shared-memory jna

如何读取共享内存部分 "全球\ something_something" 在java中创建并由c#/ c ++程序更新? 我找到了一些教程,但是他们要么使用"真正的文件"或者还有一些其他的东西。 我知道我必须通过jna进行本机调用,例如,对windows api进行本地调用,并使用类似openFileMapping函数的东西。

是否有我错过的教程或者有人可以给我一些示例代码? 使用jna或jni是java中那种东西的唯一方法吗?

1 个答案:

答案 0 :(得分:1)

如果可以获取指向内存位置的指针,则可以使用JNA的Pointer方法来访问内存。或者,您可以创建direct NIO Buffer,这有助于在Java和本机之间共享内存。

这些方法中的任何一种都应该同样适用于共享内存。

// 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

修改

解决访问Named Shared Memory Windows块的具体问题,您需要了解如何通过W32 API访问它,然后通过JNA(或JNI,如果您愿意)访问这些API。

来自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;
   }

将这些函数映射到JNA以便在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);
}

请注意,JNA的Kernel32(在platform.jar中)已包含MapViewOfFile的映射,该映射返回Pointer。使用该返回值,您可以根据内容读取和写入共享内存。