【发布时间】:2017-10-11 20:01:24
【问题描述】:
我有一个客户端和一个服务器应用程序。客户端向服务器发送字符串命令,服务器使用 JNA 对两个 DLL 库接口进行相关调用。当然,有时我会被要求在 java 端使用指针。我无法通过套接字连接发送指针对象,因为它们不可序列化。为了解决这个问题,我认为我会使用 Pointer.nativeValue(p) 获取指针的本机长值,通过连接发送该长值并使用它在客户端创建一个新指针。然而,尽管客户端的 Pointer 对象与服务器端的指针对象具有相同的本机值,但它并没有指向客户端的任何内容,并且我收到 Invalid Memory Access 错误。
现在,在我的客户端应用程序中,我正在使用 JavaFX 创建一个可以在其中绘制 DLL 的窗口,因此我必须获取 JavaFX 窗口的 HWND。然后我要做的是将 JNA 的 HWND 对象的本机值发送到服务器,然后服务器使用该长本机值重新创建 HWND 对象。这样可行。但显然 Pointer 和其他类似的 JNA 对象没有。我认为这些 Pointer 对象和 HWND 对象(以及 WinDef 类中的其他对象)之间的区别在于 HWND 实际上是一个本机值,因为它来自 Windows 本身,否则它作为本机将毫无用处窗把手。但我认为 JNA 指针仅存在于当前运行的 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。
【问题讨论】: