如何在java中創建並更新c#/ C++程序來讀取像 「Global \ something_something」 這樣的共享內存段? 我找到了一些教程,但他們或者使用「真實文件」或者有其他一些其他的東西。 我知道我必須通過jna調用本地調用,例如,使用windows api並使用類似openFileMapping函數的東西。從java中的C++/c#程序讀取共享內存
是否有教程我已經錯過或可能有人給我一點的例子代碼? 在java中使用jna或jni是唯一的方法嗎?
如何在java中創建並更新c#/ C++程序來讀取像 「Global \ something_something」 這樣的共享內存段? 我找到了一些教程,但他們或者使用「真實文件」或者有其他一些其他的東西。 我知道我必須通過jna調用本地調用,例如,使用windows api並使用類似openFileMapping函數的東西。從java中的C++/c#程序讀取共享內存
是否有教程我已經錯過或可能有人給我一點的例子代碼? 在java中使用jna或jni是唯一的方法嗎?
如果你能獲得一個指向內存位置,你可以使用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
。使用該返回值,您可以讀取和寫入共享內存以查看您心中的內容。
感謝您的回答,但我仍然有點失落。我有一個應用程序A,我沒有它的源代碼,它創建了一個名爲「Global \ application_A」的共享內存段,並且每秒更新一次數據(它不是很多數據,只有幾kb)。現在我想在java中創建一個應用程序B,它讀取A的共享內存以將其打印到控制檯。它不需要寫入權限,只能讀取。 – rmcp
請鏈接到「shared memory section」的定義的詳細信息。也許你指的是[this](https://msdn.microsoft.com/en-us/library/windows/desktop/aa366551(v = vs.85).aspx)? – technomage
是的,我認爲是。當我用sysinternal進程管理器查看進程並顯示句柄時,「Global \ application_A」顯示爲「Section」,並在其屬性中顯示「分頁文件支持的內存區域的內存映射文件」。我也可以看到那裏的地址,如「0xFFFFC00203422520」,雖然我不認爲這有幫助。 – rmcp
也許你是完全正確和應該前往一些低層次的語言(C?) –
使用內存映射文件實現了一個基於JNI的解決辦法是做在Java中沒有額外的本地代碼的唯一途徑。但是,只要不廣泛地調用同步,「真實」臨時文件和任何其他創建共享內存的方式之間沒有區別。 – Holger