Last active
October 5, 2024 11:32
-
-
Save santa4nt/4a8fd626335e36c94356 to your computer and use it in GitHub Desktop.
Sample JNI/C++ HelloWorld
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
public class HelloJNI { | |
static { | |
System.loadLibrary("hello"); // loads libhello.so | |
} | |
private native void sayHello(String name); | |
public static void main(String[] args) { | |
new HelloJNI().sayHello("Dave"); | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include "HelloJNIImpl.h" | |
#include <memory> | |
#include <functional> | |
#include <iostream> | |
#include <jni.h> | |
#include "HelloJNI.h" // auto-generated by `javah HelloJNI` | |
using std::string; | |
using std::function; | |
using std::unique_ptr; | |
using std::shared_ptr; | |
using std::cout; | |
using std::endl; | |
class jstring_deleter | |
{ | |
JNIEnv *m_env; | |
jstring m_jstr; | |
public: | |
jstring_deleter(JNIEnv *env, jstring jstr) | |
: m_env(env) | |
, m_jstr(jstr) | |
{ | |
} | |
void operator()(const char *cstr) | |
{ | |
cout << "[DEBUG] Releasing " << cstr << endl; | |
m_env->ReleaseStringUTFChars(m_jstr, cstr); | |
} | |
}; | |
const string ToString(JNIEnv *env, jstring jstr) | |
{ | |
jstring_deleter deleter(env, jstr); // using a function object | |
unique_ptr<const char, jstring_deleter> pcstr( | |
env->GetStringUTFChars(jstr, JNI_FALSE), | |
deleter ); | |
return string( pcstr.get() ); | |
} | |
shared_ptr<const char> ToStringPtr(JNIEnv *env, jstring jstr) | |
{ | |
function<void(const char*)> deleter = // using a lambda | |
[env, jstr](const char *cstr) -> void | |
{ | |
cout << "[DEBUG] Releasing " << cstr << endl; | |
env->ReleaseStringUTFChars(jstr, cstr); | |
}; | |
return shared_ptr<const char>( | |
env->GetStringUTFChars(jstr, JNI_FALSE), | |
deleter ); | |
} | |
/* | |
* Class: HelloJNI | |
* Method: sayHello | |
* Signature: (Ljava/lang/String;)V | |
*/ | |
JNIEXPORT void JNICALL Java_HelloJNI_sayHello | |
(JNIEnv *env, jobject thisObj, jstring arg) | |
{ | |
DoSayHello(ToString(env, arg)); | |
//const string name = ToStringPtr(env, arg).get(); | |
//DoSayHello(name); | |
} | |
void DoSayHello(const string &name) | |
{ | |
cout << "Hello, " << name << endl; | |
} | |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#ifndef _HELLO_JNI_IMPL_H | |
#define _HELLO_JNI_IMPL_H | |
#include <string> | |
void DoSayHello(const std::string &name); | |
#endif//_HELLO_JNI_IMPL_H |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
export JAVA_INC=/usr/lib/jvm/java-7-oracle/include | |
# step 1: compile the .class file with invocation to a native method | |
javac HelloJNI.java | |
# step 2: auto-generate a .h header file from said Java source | |
javah HelloJNI | |
# step 3: make the shared library with the name linked in said Java source, and implementing said native method | |
g++ -std=c++11 -shared -fPIC -I$JAVA_INC -I$JAVA_INC/linux HelloJNIImpl.cpp -o libhello.so | |
# step 4: run JVM with java.library.path set to include said shared library | |
java -Djava.library.path=. HelloJNI |
Nice
Thanks
This gist helped me a lot.
Thanks
Thanks, this hist helped me.
This is outdated at this point. javah
was removed in JDK 10. The modern equivalent of line 6 (JDK >= 10) in makerun.sh
is javac -h . HelloJNI
.
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Thanks a lot for this guide! It is also very interesting how use this with Gradle.