I have a client and a server application. The client sends String commands to the server, which uses JNA to make relevant calls to two DLL library interfaces. Naturally, I will be required at some point to use Pointers on the java side of things.I am unable to send Pointer objects over the socket connection as they are not serializable. To get around this, I thought that I would get the native long value of the Pointer using Pointer.nativeValue(p), send that long value over the connection and use it to create a new Pointer on the client side. However, though the Pointer object on the client side has the same native value of the one on the server side, it does not point to anything on the client side and I get an Invalid Memory Access error.
Now, in my client application I am using JavaFX to create a window within which my DLLs can draw, so I have to get the HWND of the JavaFX window. What I then do is send the native value of JNA's HWND object to the server, which then recreates the HWND object using that long native value. THAT works. But obviously the Pointer and those other similar JNA objects do not. I think the difference between those Pointer objects and the HWND object (as well as the others in the WinDef class) is that the HWND is actually a native value, as in it comes from Windows itself, otherwise it would be pretty useless as a native window handle. But I think that JNA Pointers exist only within the currently running JRE. So transferring that pointer value to another JRE (where my client is running) will not work. I'm really not 100% sure about any of this.
I'm only a beginner at C programming and so I don't know all that much about pointers, much less C pointers in java. But please can someone let me know if I have the right idea about this and explain it further, particularly about how these Pointers work within java.
Here's just an example of what I did:
// 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);
}
I also tried this with IntByReference. Although it did not throw an error as with the Pointer object, the value set on the server side was 1234 but the value I got on the client side was 0.
The value of a pointer is an address in the process's address space. On an OS featuring a virtual memory subsystem (including all general-purpose OSs you will meet, and Windows in particular), such an address is inherently particular to the process. One process cannot access the memory of another, whether via a pointer or otherwise. This kind of memory protection is an intentional and highly desirable feature.
On the other hand, a given OS may provide for resources with machine scope. On MS Windows, a window is such a resource, and its handle designates the same window to every process.