{"id":19532026,"url":"https://github.com/jmarkstar/jni_exercises","last_synced_at":"2026-05-12T13:37:31.410Z","repository":{"id":96741938,"uuid":"125738811","full_name":"jmarkstar/JNI_Exercises","owner":"jmarkstar","description":"Some examples about JNI - Java \u003c-\u003e C","archived":false,"fork":false,"pushed_at":"2018-03-21T20:28:26.000Z","size":58,"stargazers_count":3,"open_issues_count":0,"forks_count":0,"subscribers_count":2,"default_branch":"master","last_synced_at":"2025-01-08T17:06:05.763Z","etag":null,"topics":["c","java","jni"],"latest_commit_sha":null,"homepage":"","language":"C","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/jmarkstar.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2018-03-18T15:25:43.000Z","updated_at":"2018-05-07T19:31:49.000Z","dependencies_parsed_at":null,"dependency_job_id":"e2b35ac6-5efc-4994-891a-9400fc73989b","html_url":"https://github.com/jmarkstar/JNI_Exercises","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jmarkstar%2FJNI_Exercises","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jmarkstar%2FJNI_Exercises/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jmarkstar%2FJNI_Exercises/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jmarkstar%2FJNI_Exercises/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/jmarkstar","download_url":"https://codeload.github.com/jmarkstar/JNI_Exercises/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":240784058,"owners_count":19856941,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["c","java","jni"],"created_at":"2024-11-11T01:45:49.660Z","updated_at":"2026-05-12T13:37:26.387Z","avatar_url":"https://github.com/jmarkstar.png","language":"C","funding_links":[],"categories":[],"sub_categories":[],"readme":"# JNI Exercises\n\n## Simple example on macOS \n\nCreate the java file. `HelloWorld.java`\n\nExecute `javac HelloWorld.java `, this generate a `HelloWorld.class` file.\n\nAfter that, generate the C Header executing `javah -jni HelloWorld`, you'll get `HelloWorld.h` file.\n\nCreate a C file. `HelloWorld.c`.\n\nImplement the C functions.\n\nCompile C file with this command on macOS.\n\n`gcc -c -Wall -Werror -fpic HelloWorld.c -I${JAVA_HOME}/include -I${JAVA_HOME}/include/darwin`\n\n`-I flag` adds other C files needed like `jni.h` and `jni_md.h`.\n\nThis command will generate a `HelloWorld.o` file.\n\nThen, you should create a shared library from the `*.o` file using this command.\n\n`gcc -shared -o libHelloWorld.dylib HelloWorld.o`\n\nThis command will generate a `libHelloWorld.dylib` file.\n\nIf you have all the files on the same directory you should have the following files.\n\n* HelloWorld.java\n* HelloWorld.class\n* HelloWorld.h\n* HelloWorld.c\n* HelloWorld.o\n* HelloWorld.dylib\n\nFinally, Execute the java class.\n\n`java HelloWorld -Djava.library.path=libHelloWorld.dylib`\n\n### Recipes\n\n##### Recipe 01 HelloWorld\n\nThe first recipe is a simple HelloWorld.\n\n##### Recipe 02 Native Types\n\nIn this recipe I'm passing the Java Primitive Types to C where will be converted to the appropiate Native Type. [More information](https://docs.oracle.com/javase/7/docs/technotes/guides/jni/spec/types.html)\n\n| Java Primitive Types        | JNI Types           | C Type | Description     |\n| ------------ |:------:| -----:|-------:|\n| byte | jbyte | signed char | signed 8 bits |\n| short | jshort | short | signed 16 bits |\n| int | jint | int |signed 32 bits |\n| long | jlong | long long  |signed 64 bits |\n| float | jfloat | float| 32 bits |\n| double | jdouble | double  | 64 bits |\n| boolean  | jboolean | unsigned char | unsigned 8 bits |\n| char | jchar | unsigned short | unsigned 16 bits |\n| void | void | N/A | N/A |\n\n`signed` means that the type can represent negavite numbers; `unsigned` cannot.\n\n##### Recipe 03 Strings\n\nIn this recipe I'm passing Strings and using some JNI methods like:\n\nUTF-8\n\n* `GetStringUTFChars()` Convert `jstring` to `const char *`.\n* `ReleaseStringUTFChars()` Release memory\n* `NewStringUTF()` Create new string\n* `GetStringUTFLength()` get the `jsize` of the string.\n\nUnicode\n\n* `GetStringChars()` Convert `jstring` to `const char *`.\n* `ReleaseStringChars()` Release memory\n* `NewString()` Create new string\n* `GetStringLength()` get the `jsize` of the string.\n\n`jsize` is an alias, its real type is `jint`.\n\n`typedef jint jsize;`\n\n\n\n[More information](http://www.softlab.ntua.gr/facilities/documentation/unix/java/tutorial/native1.1/implementing/string.html)\n\n##### Recipe 04 Arrays\n\n* GetArrayLength(env, array)\n\n\tReturns the number of elements in the array.\n\n\t`jsize length = (*env)-\u003eGetArrayLength(env, array);`\n\n* Get[ **PrimitiveType** ]ArrayElements(env, array, 0) Routines\n\n\t`jboolean *body = (*env)-\u003eGetBooleanArrayElements(env, array, 0);`\n\n* New[ **PrimitiveType** ]Array Routines\n\n\tA family of operations used to construct a new \tprimitive array object.\n\t\n\t| New\u003cPrimitiveType\u003eArray Routines | Array Type |\n\t|----|---|\n\t| NewBooleanArray() | jbooleanArray |\n\t| NewByteArray() | jbyteArray |\n\t| NewCharArray() | jcharArray |\n\t| NewShortArray() | jshortArray |\n\t| NewIntArray() | jintArray |\n\t| NewLongArray() | jlongArray |\n\t| NewFloatArray() | jfloatArray |\n\t| NewDoubleArray() | jdoubleArray |\n\t\n\t`jintArray  = (*env)-\u003eNewIntArray(env, size);`\n\t\n* Set[ **PrimitiveType** ]ArrayRegion Routines\n\t\n\tA family of functions that copies back a region of a primitive array from a buffer.\n\n\t```\n\tjintArray  = (*env)-\u003eNewIntArray(env, size);\n\t\n\tjint start = 0;\n\tjint length = 10;\n\tjint tempArray [size];\n\t\n\t(*env)-\u003eSetIntArrayRegion(env, javaArray, start, length, tempArray);\n\t```\n\t\n* Release[ **PrimitiveType** ]ArrayElements(env, array, body, **mode**) Routines\n\n| mode | actions |\n|----|---|\n| 0 | copy back the content **and** free the elems buffer |\n| JNI_COMMIT | copy back the content but **dont** free the elems buffer.|\n| JNI_ABORT | free the buffer without copying back the possible changes|\n\n##### Recipe 05 Fields and Methods\n\n###### Fields \n\nJava supports two kinds of fields: instance fields and static fields.\n\n* GetObjectClass(env, obj) Gets the class reference.\n\n* GetFieldID(env, classReference, fieldName, fieldSignature) Gets the field ID.\n\n* GetObjectField() Gets the field reference.\n\n* SetObjectField() Sets the value of an instance (nonstatic) field of an object. \n\n* GetStaticFieldID() Returns the field ID for a static field of a class. \n\n* GetStatic[ **PrimitiveType** ]Field() Returns the value of a static field of an object.\n\n* SetStatic[ **PrimitiveType** ]Field() Sets the value of a static field of an object. \n\n**JNI field signature** \n\nWe can use the **javap** tool to geneate the field descriptors from the class files. Normally javap prints out the method and field types in a given class. \n\nIf we specify the **-s** option It will print the field descriptors.\n\nIf we specify the **-p** option It will print the field descriptors of private members. [More Info](https://communities.ca.com/docs/DOC-99575135)\n\n`javap -s -p MyClass`\n\n###### Methods\n\n* GetMethodID(env, classReference, methodname, signature) performs a lookup for the method in the given class.\n\n* Call[ **PrimitiveType** ]Method() invokes an instance method that has the return type [ **PrimitiveType** ] or **Object**.\n\n* GetStaticMethodID() performs a lookup for the static method in the given class.\n\n* CallStatic[ **PrimitiveType** ]Method() invokes an static method that has the return type [ **PrimitiveType** ] or **Object**.\n\n##### Recipe 06 Local and Global references\n\nThe JNI supports three kinds of opaque references: **local references**, **global references**, and **weak global references**.\n\nLocal and global references have different lifetimes. Local references are automatically freed, whereas global and weak global references remain valid until they are freed by the programmer.\n\nA local or global reference keeps the referenced object from being garbage collected. A weak global reference, on the other hand, allows the referenced object to be garbage collected.\n\n###### Local References\n\nA local reference is valid only within the dynamic context of the native method that creates it, and only within that one invocation of the native method.\n\nAll local references created during the execution of a native method will be freed once the native method returns.\n\nLocal references are also only valid in the thread that creates them. \n\n###### Global References\n\nYou can use a global reference across multiple invocations of a native method. A global reference can be used across multiple threads and remains valid until it is freed by the programmer. Like a local reference, a global reference ensures that the referenced object will not be garbage collected.\n\n* NewGlobalRef(env, obj) is the only method to create global references.\n\n* DeleteGlobalRef(env, obj) deletes a global reference.\n\n###### Weak Global References\n\nLike global refer- ences, weak global references remain valid across native method calls and across different threads. Unlike global references, weak global references do not keep the underlying object from being garbage collected.\n\n* NewGlobalWeakRef(env, obj) \n\n* DeleteGlobalWeakRef()\n\n##### Recipe 07 Exceptions \n\n* ExceptionCheck(env) Checks for pending exceptions without creating a local reference to the exception object. It returns JNI_TRUE or JNI_FALSE.\n\n* ExceptionOccurred() Determines if an exception is \tbeing thrown. The exception stays being thrown \tuntil either the native code calls \t\tExceptionClear(), or the Java code handles the \texception. \n\n\tReturns the exception object that is currently in \tthe process of being thrown, or NULL if no \texception is currently being thrown.\n\n* ExceptionDescribe() Prints an exception and a backtrace of the stack to a system error-reporting channel, such as stderr. This is a convenience routine provided for debugging.\n\n* ExceptionClear() Clears any exception that is currently being thrown. If no exception is currently being thrown, this routine has no effect.\n\n* ThowNew(env, exceptionClassRef, \"Message\")\n\n## More of JNI \n\n##### JNIEnv interface pointer \n\nPoints to a location that contains a pointer to a function table. Each entry in the function table points to a JNI function. Native methods always access data structures in the Java virtual machine through one of the JNI functions.\n\n##### jni.h and jni_md\n\n`jni.h` contains the JNI types and functions to communicate Java and Native Libraries.\n\n`jni_md.h` contains the machine-dependent typedefs for jbyte, jint\n   and jlong.\n\n## C stuffs\n\n`typedef` is a keyword in the C and C++ languages to create an alias name for another data type.\n\n`#define` allows constant values.\n\n`#ifdef` and `#endif` directive allows for conditional compilation\n\n### References\n\nhttp://journals.ecs.soton.ac.uk/java/tutorial/native1.1/implementing/array.html\n\nhttps://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html\n\n\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fjmarkstar%2Fjni_exercises","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fjmarkstar%2Fjni_exercises","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fjmarkstar%2Fjni_exercises/lists"}