2015-09-07 155 views
0

如何在java中创建并更新c#/ C++程序来读取像 “Global \ something_something” 这样的共享内存段? 我找到了一些教程,但他们或者使用“真实文件”或者有其他一些其他的东西。 我知道我必须通过jna调用本地调用,例如,使用windows api并使用类似openFileMapping函数的东西。从java中的C++/c#程序读取共享内存

是否有教程我已经错过或可能有人给我一点的例子代码? 在java中使用jna或jni是唯一的方法吗?

+0

也许你是完全正确和应该前往一些低层次的语言(C?) –

+0

使用内存映射文件实现了一个基于JNI的解决办法是做在Java中没有额外的本地代码的唯一途径。但是,只要不广泛地调用同步,“真实”临时文件和任何其他创建共享内存的方式之间没有区别。 – Holger

回答

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访问那些API(或JNI,如果你喜欢)。

从MS文档:

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中映射这些功能集成到JNA使用:

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。使用该返回值,您可以读取和写入共享内存以查看您心中的内容。

+0

感谢您的回答,但我仍然有点失落。我有一个应用程序A,我没有它的源代码,它创建了一个名为“Global \ application_A”的共享内存段,并且每秒更新一次数据(它不是很多数据,只有几kb)。现在我想在java中创建一个应用程序B,它读取A的共享内存以将其打印到控制台。它不需要写入权限,只能读取。 – rmcp

+0

请链接到“shared memory section”的定义的详细信息。也许你指的是[this](https://msdn.microsoft.com/en-us/library/windows/desktop/aa366551(v = vs.85).aspx)? – technomage

+0

是的,我认为是。当我用sysinternal进程管理器查看进程并显示句柄时,“Global \ application_A”显示为“Section”,并在其属性中显示“分页文件支持的内存区域的内存映射文件”。我也可以看到那里的地址,如“0xFFFFC00203422520”,虽然我不认为这有帮助。 – rmcp