将JNA指针从一个Java应用程序发送到另一个Java应用程序

我有一个客户端和一个服务器应用程序。 客户端将String命令发送到服务器,该服务器使用JNA对两个DLL库接口进行相关调用。 当然,我会在某些时候需要在java方面使用Pointers。我无法通过套接字连接发送Pointer对象,因为它们不可序列化。 为了解决这个问题,我想我会使用Pointer.nativeValue(p)获取指针的原生长值,在连接上发送该长值并使用它在客户端创建新的指针。 但是,尽管客户端上的Pointer对象与服务器端的Pointer对象具有相同的本机值,但它并未指向客户端上的任何内容,并且出现Invalid Memory Access错误。

现在,在我的客户端应用程序中,我使用JavaFX创建一个窗口,我的DLL可以在其中绘制,因此我必须得到JavaFX窗口的HWND。 然后我做的是将JNA的HWND对象的本机值发送到服务器,然后服务器使用该长本机值重新创建HWND对象。 这样可行。 但很明显,Pointer和其他类似的JNA对象没有。 我认为这些Pointer对象和HWND对象(以及WinDef类中的其他对象)之间的区别在于HWND实际上是一个本机值,因为它来自Windows本身,否则它作为本机就没用了窗把手。 但我认为JNA Pointers仅存在于当前运行的JRE中。 因此,将指针值传递给另一个JRE(我的客户端正在运行)将无法正常工作。 我真的不是100%肯定这一点。

我只是C编程的初学者,所以我对指针知之甚少,更不用说java中的C指针了。 但是如果我对此有正确的想法并且进一步解释,请有人告诉我,特别是关于这些指针如何在java中工作。

这只是我所做的一个例子:

// Server side (PointerTest class) public long getPtrVal() { Pointer p = new Memory(100); p.setString(0, "Test"); long ptrVal = Pointer.nativeValue(p); return ptrVal; // return value is processed in separate class } // Client side (MyClient sends String command, returns Object) public static void main(String[] args) { MyClient c = new MyClient(); long ret = (long) c.sendCommand("PointerTest"); Pointer p = new Pointer(ret); String pointerString = p.getString(0); System.out.println(pointerString); } 

我也尝试使用IntByReference。 虽然它没有像Pointer对象那样抛出错误,但是服务器端设置的值是1234,但是我在客户端获得的值是0。

指针的值是进程地址空间中的地址。 在具有虚拟内存子系统(包括您将遇到的所有通用操作系统,特别是Windows)的操作系统上,此类地址本身就是该过程所特有的。 一个进程无法通过指针或其他方式访问另一个进程的内存。 这种记忆保护是一种有意和非常理想的特征。

另一方面,给定的OS可以提供​​具有机器范围的资源。 在MS Windows上,窗口就是这样的资源,它的句柄为每个进程指定相同的窗口。