JNIEnv
JNI 변수 타입
JAVA | C++/C | C++/C 배열 |
boolean | jboolean | jbooleanArray |
byte | jbyte | jbytArray |
char | jchar | jcharArray |
short | jshort | jshortArray |
int | jint | jintArray |
long | jlong | jlongArray |
float | jfloat | jfloatArray |
void | jvoid | jvoidArray |
Object | jobject | jobjectArray |
String | jstring | jstringArray |
JNI 시그니처
시그니처 | Type |
B | byte |
C | char |
D | double |
F | float |
I | int |
J | long |
S | short |
V | void |
Z | boolean |
L클래스_이름 | 패키지 경로/ 클래스 이름 |
[ type | type[] 배열 |
자바 클래스 호출 방법
- JNI 변수 타입 및 시그니처 정보 (JNI Signiture) :: 루지
- c - Android NDK crash in CallObjectMethod calling getSystemService - Stack Overflow
- Access android context in ndk application - Stack Overflow
Example
jstring toUpperString
(
JNIEnv *env,
jobject thiz,
jstring str
)
{
//create String instance
//find the string class
jclass stringClass = env->FindClass("java/lang/String");
if(stringClass == nullptr) {
std::cout << "Failed to find the String class" << std::endl;
return nullptr;
}
//find the contructor id
jmethodID constructorID = env->GetMethodID(stringClass, "<init>", "(Ljava/lang/String;)V");
if(constructorID == nullptr) {
std::cout << "Failed to find the constructor of String class" << std::endl;
return nullptr;
}
jstring stringObject = static_cast<jstring>( env->NewObject(stringClass, constructorID, str) );
//find the toUpperCase Method
jmethodID toUpperCaseID = env->GetMethodID(stringClass, "toUpperCase", "()Ljava/lang/String;");
if(toUpperCaseID == nullptr) {
std::cout << "Failed to find the toUpperCase method" << std::endl;
return nullptr;
}
//call method
return static_cast<jstring>(env->CallObjectMethod(stringObject, toUpperCaseID));
}
jstring toLowerString
(
JNIEnv *env,
jobject thiz,
jstring str
)
{
//find the string class
jclass stringClass = env->FindClass("java/lang/String");
if(stringClass == nullptr) {
std::cout << "Failed to find the String class" << std::endl;
return nullptr;
}
//find the toLowerCase Method
jmethodID toLowerCaseID = env->GetMethodID(stringClass, "toLowerCase", "()Ljava/lang/String;");
if(toLowerCaseID == nullptr) {
std::cout << "Failed to find the toLowerCase method" << std::endl;
return nullptr;
}
//call method
return static_cast<jstring>(env->CallObjectMethod(str, toLowerCaseID));
}
void doJobAndThenCallback
(
JNIEnv *env,
jobject thiz,
jint value
)
{
//find the class of thiz object
jclass thizClass = env->GetObjectClass(thiz);
//find the onStart Method
jmethodID onStartID = env->GetMethodID(thizClass, "onStart", "()V");
if(onStartID == nullptr) {
std::cout << "Failed to find the onStart method" << std::endl;
return;
}
//call the onStart callback Method
env->CallVoidMethod(thiz, onStartID);
//do some jobs
for(auto i=0; i<value; ++i) {
std::cout << i << " ";
}
std::cout << std::endl;
//find the onFinish Method
jmethodID onFinishID = env->GetMethodID(thizClass, "onFinish", "()V");
if(onFinishID == nullptr) {
std::cout << "Failed to find the onFinish method" << std::endl;
return ;
}
//call the onFinish callback Method
env->CallVoidMethod(thiz, onFinishID);
}
JNIEXPORT jint JNICALL JNI_OnLoad
(
JavaVM *vm,
void *reserved
)
{
JNIEnv *env;
if(vm->GetEnv(reinterpret_cast<void**>(&env), JNI_VERSION_1_6)) {
return -1;
}
JNINativeMethod nm[3] ={
{
const_cast<char*>("toUpperString"),
const_cast<char*>("(Ljava/lang/String;)Ljava/lang/String;"),
reinterpret_cast<void*>(toUpperString)
}
,
{
const_cast<char*>("toLowerString"),
const_cast<char*>("(Ljava/lang/String;)Ljava/lang/String;"),
reinterpret_cast<void*>(toLowerString)
}
,
{
const_cast<char*>("doJobAndThenCallback"),
const_cast<char*>("(I)V"),
reinterpret_cast<void*>(doJobAndThenCallback)
}
};
jclass cls = env->FindClass("Client");
env->RegisterNatives(cls, nm, 3);
return JNI_VERSION_1_6;
}