如何在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