如何读取共享内存部分 "全球\ something_something" 在java中创建并由c#/ c ++程序更新? 我找到了一些教程,但是他们要么使用"真正的文件"或者还有一些其他的东西。 我知道我必须通过jna进行本机调用,例如,对windows api进行本地调用,并使用类似openFileMapping函数的东西。
是否有我错过的教程或者有人可以给我一些示例代码? 使用jna或jni是java中那种东西的唯一方法吗?
答案 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
。使用该返回值,您可以根据内容读取和写入共享内存。