问题
How can I read a shared memory section like "Global\something_something" in java that was created and is updated by a c#/c++ program? I found some tutorials, but they either work with "real files" or have some other additional stuff. I know that I have to make native calls via jna, for example, to the windows api and use something like the openFileMapping function.
Are there tutorials I have missed or could someone give me a bit of example code? Is using jna or jni the only way to that sort of thing in java?
回答1:
If you can obtain a pointer to the memory location, you can use JNA's Pointer
methods to access the memory. Alternatively you can create a direct NIO Buffer, which facilitates sharing memory between Java and native.
Any one of these methods should work equally well for sharing memory.
// 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();
If you want to share more than available physical memory, then you'd be better off using a file-based mapping.
EDIT
Addressing the specific question of accessing a Windows block of Named Shared Memory, you need to understand how to access it via w32 APIs and then access those APIs via JNA (or JNI, if you prefer).
From the 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;
}
It's a straightforward matter to map these functions into JNA for use in 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);
}
Note that JNA's Kernel32
(in platform.jar
) already includes a mapping for MapViewOfFile
, which returns a Pointer
. Using that returned value, you can read and write to the shared memory to your heart's content.
来源:https://stackoverflow.com/questions/32440527/reading-shared-memory-from-c-c-program-in-java