-
Notifications
You must be signed in to change notification settings - Fork 6
Sizes
Java and C++ differ in how they represent notion of size.
Java generally uses signed quantities for it: jint
(32-bit) or jlong
(64-bit).
Standard C++ uses unsigned size_t
(32-bit on 32-bit OSes, 64-bit on 64-bit ones).
For normal sizes your code is likely to deal with most of the time the difference is academic. Both sides can represent such sizes easily. The problem arise in two cases or their combination:
- When Java uses negative size value to represent something. An error perhaps or "not found" or some such.
- When you need to deal with huge data which size exceeds the maximum positive value of a signed Java size but still fits into the C++ one.
If you simply pass jint
or jlong
where size_t
is needed and vice versa both issues can create unpleasant bugs that are often not easily found in normal unit testing or debugging. If you are lucky the invalid value will immediately result in exception on the other side and will be fast to diagnose and fix. If you aren't the invalid value will chug along in the code for a long while creating a buffer overflow much later in an unrelated code.
The good thing about this situation is that C++ compilers will generally warn when you have such implicit conversions. The bad thing is that the first instinct of most C++ programmers is to shut the warning up by adding an explicit cast. This makes the code compile and pass the tests but does nothing to address the underlying issue.
SimpleJNI cannot solve the root cause of the issue but it enables you to at least fail fast - crash immediately right where the problem occurs. To this end it provide two functions:
jsize size_to_java(size_t size);
size_t java_size_to_cpp(jsize size);
That should be used instead of cast to "silence compiler warnings". Unlike a cast these call std::terminate if the input value cannot be properly converted to the output type. Crashing isn't ideal but it is better than introduce a buffer overflow or corrupt user's data.
- Building
-
User's Guide
Declaring Java Types
Accessing Methods and Fields
Representing Java Classes
Implementing Native Methods
Smart References
Error Handling
Obtaining JNIEnv
Initialization
Strings
Arrays
Direct Buffers
Booleans
Sizes -
JniGen Code Generator
Integrating JniGen
Annotations
Processor Options