将 JNA 指针从一个 Java 应用程序发送到另一个 Java 应用程序
Sending a JNA Pointer from one Java application to another Java application
我有一个客户端和一个服务器应用程序。客户端向服务器发送String命令,服务器使用JNA对两个DLL库接口进行相关调用。自然地,有时我会被要求在 things.I 的 java 端使用指针 我无法通过套接字连接发送指针对象,因为它们不可序列化。为了解决这个问题,我想我会使用 Pointer.nativeValue(p) 获取 Pointer 的本机 long 值,通过连接发送该 long 值并使用它在客户端创建一个新的 Pointer。但是,尽管客户端的指针对象与服务器端的指针对象具有相同的本机值,但它没有指向客户端的任何内容,我收到无效内存访问错误。
现在,在我的客户端应用程序中,我正在使用 JavaFX 创建一个 window,我的 DLL 可以在其中绘制,因此我必须获取 JavaFX window 的 HWND。然后我要做的是将 JNA 的 HWND 对象的本机值发送到服务器,然后服务器使用该长本机值重新创建 HWND 对象。这样可行。但显然 Pointer 和其他类似的 JNA 对象没有。我认为那些 Pointer 对象和 HWND 对象(以及 WinDef class 中的其他对象)之间的区别在于 HWND 实际上是一个本地值,因为它来自 Windows 本身,否则作为本机 window 句柄,它将毫无用处。但我认为 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。
指针的值是进程地址中的一个地址space。在具有虚拟内存子系统(包括您将遇到的所有通用 OS,尤其是 Windows)的 OS 上,这样的地址本质上是特定于进程的。一个进程无法访问另一个进程的内存,无论是通过指针还是其他方式。这种内存保护是一种有意且非常需要的功能。
另一方面,给定的 OS 可以提供具有机器范围的资源。在 MS Windows 上,一个 window 就是这样一个资源,它的句柄指定相同的 window 给每个进程。
我有一个客户端和一个服务器应用程序。客户端向服务器发送String命令,服务器使用JNA对两个DLL库接口进行相关调用。自然地,有时我会被要求在 things.I 的 java 端使用指针 我无法通过套接字连接发送指针对象,因为它们不可序列化。为了解决这个问题,我想我会使用 Pointer.nativeValue(p) 获取 Pointer 的本机 long 值,通过连接发送该 long 值并使用它在客户端创建一个新的 Pointer。但是,尽管客户端的指针对象与服务器端的指针对象具有相同的本机值,但它没有指向客户端的任何内容,我收到无效内存访问错误。
现在,在我的客户端应用程序中,我正在使用 JavaFX 创建一个 window,我的 DLL 可以在其中绘制,因此我必须获取 JavaFX window 的 HWND。然后我要做的是将 JNA 的 HWND 对象的本机值发送到服务器,然后服务器使用该长本机值重新创建 HWND 对象。这样可行。但显然 Pointer 和其他类似的 JNA 对象没有。我认为那些 Pointer 对象和 HWND 对象(以及 WinDef class 中的其他对象)之间的区别在于 HWND 实际上是一个本地值,因为它来自 Windows 本身,否则作为本机 window 句柄,它将毫无用处。但我认为 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。
指针的值是进程地址中的一个地址space。在具有虚拟内存子系统(包括您将遇到的所有通用 OS,尤其是 Windows)的 OS 上,这样的地址本质上是特定于进程的。一个进程无法访问另一个进程的内存,无论是通过指针还是其他方式。这种内存保护是一种有意且非常需要的功能。
另一方面,给定的 OS 可以提供具有机器范围的资源。在 MS Windows 上,一个 window 就是这样一个资源,它的句柄指定相同的 window 给每个进程。