Accessing JNA Pointer's peer value

The name of the pictureThe name of the pictureThe name of the pictureClash Royale CLAN TAG#URR8PPP



Accessing JNA Pointer's peer value



I'm using JNA. The Pointer class represents a native pointer. It seems quite common to access the pointer's address which seems to be the peer member variable. However, they made sure you can't query it. Why? What's the recommended way to getting it if you want to work with it?


JNA


Pointer


peer



I wrote the following "hack":


public static long getBaseAddress(Pointer pointer)

String stringPointer = pointer.toString();
String splitStringPointer = stringPointer.split("@");
int expectedSplitLength = 2;

if (splitStringPointer.length != expectedSplitLength)

throw new IllegalStateException("Expected a length of "
+ expectedSplitLength + " but got " + splitStringPointer.length);


String hexadecimalAddress = splitStringPointer[1].substring("0x".length());
return parseLong(hexadecimalAddress, 16);



But isn't there a proper way other than abusing the toString() method for grabbing the address?


toString()



I want to use Reflection even less than the approach above since it is also brittle.


Reflection





There are good reasons outlined by Stephen as to why this shouldn't be done. That said, when faced with a choice between parsing toString and reflection, you should almost certainly prefer reflection. Although both are brittle, reflection is much more suitable for inspecting members of a class as you are doing here, as compared to parsing toString.
– Andrey Akhmetov
Aug 12 at 5:24





@AndreyAkhmetov: Can you please link to the statement by Stephen (whoever he is)?
– BullyWiiPlaza
Aug 12 at 9:15






Stephen deleted his answer, but it was up on this post at the time of writing of my comment. I don't know why he deleted it and I can't validate it to be true, but my statement about reflection vs toString still stands.
– Andrey Akhmetov
Aug 12 at 16:38




2 Answers
2



While subclassing (as in technomage's answer) works, it's unnecessary and not that hard to get the peer value. Pointer.nativeValue(p) will give you p's peer.


peer


Pointer.nativeValue(p)


p



And as in my comment to the other answer, "Don't use this unless you know what you're doing." It's generally not needed for anything inside JNA. Only if you actually need the memory address for some other purpose is the peer value truly relevant. You can iterate an offset value from 0 to accomplish idioms like the code sample in your link.



The Pointer's getters all take an offset argument, and you can also simply return a pointer to an offset from the original peer value using share().


offset


share()





Thank you, this is the more proper solution.
– BullyWiiPlaza
Aug 15 at 9:51



Make a subclass of Pointer and you can do whatever you'd like with the protected field.


Pointer



Generally, you shouldn't access the value directly, the intent of making the field protected is exactly to make it hard to make such mistakes inadvertently.





How is accessing the value directly a mistake if you want to keep incrementing it like in this C++ code example? stackoverflow.com/a/28232548/3764804 1. Get the value 2. Increment 3. Make a new Pointer object 4. Repeat It's perfectly fine, isn't it?
– BullyWiiPlaza
Aug 13 at 21:53



C++


Pointer





@BullyWiiPlaza not so much a mistake as a "generally you shouldn't". As the Javadoc for the constructor with the peer states, "Don't use this unless you know what you're doing." There are other ways (e.g., offsets, share(), etc.) to access memory at an offset from the original pointer that I find preferable. YMMV.
– Daniel Widdis
Aug 14 at 22:16


share()






By clicking "Post Your Answer", you acknowledge that you have read our updated terms of service, privacy policy and cookie policy, and that your continued use of the website is subject to these policies.

Popular posts from this blog

Firebase Auth - with Email and Password - Check user already registered

Dynamically update html content plain JS

How to determine optimal route across keyboard