有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

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

我有一个客户端和一个服务器应用程序。客户端向服务器发送字符串命令,服务器使用JNA对两个DLL库接口进行相关调用。当然,我会在某个时候被要求在java方面使用指针。我无法通过socket连接发送指针对象,因为它们不可序列化。为了解决这个问题,我想我应该使用指针获得指针的本机long值。nativeValue(p),通过连接发送长值,并使用它在客户端创建新指针。然而,尽管客户端的指针对象与服务器端的指针对象具有相同的本机值,但它没有指向客户端的任何对象,因此我得到了一个无效的内存访问错误

现在,在我的客户端应用程序中,我使用JavaFX创建了一个窗口,我的DLL可以在其中绘制,所以我必须获得JavaFX窗口的HWND。然后我要做的是将JNA的HWND对象的本机值发送到服务器,然后服务器使用该长本机值重新创建HWND对象。行得通。但很明显,指针和其他类似的JNA对象并不是这样。我认为这些指针对象和HWND对象(以及WinDef类中的其他对象)之间的区别在于,HWND实际上是一个本机值,因为它来自Windows本身,否则它作为本机窗口句柄将非常无用。但我认为JNA指针只存在于当前运行的JRE中。因此,将指针值传输到另一个JRE(我的客户机正在运行)将不起作用。我真的不是百分之百确定

我只是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。虽然它没有像指针对象那样抛出错误,但在服务器端设置的值是1234,而在客户端设置的值是0


共 (1) 个答案

  1. # 1 楼答案

    指针的值是进程地址空间中的地址。在一个具有虚拟内存子系统的操作系统上(包括您将遇到的所有通用操作系统,尤其是Windows),这样的地址在本质上是进程特有的。一个进程无法访问另一个进程的内存,无论是通过指针还是其他方式。这种内存保护是一种有意且非常理想的功能

    另一方面,给定的操作系统可以提供机器范围的资源。在MS Windows上,窗口就是这样一种资源,其句柄为每个进程指定相同的窗口