2015-09-07 80 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