如何从C库

时间:2016-05-06 09:17:29

标签: android android-ndk java-native-interface

我目前正在使用android studio开发Android应用程序,对于这个项目,我需要使用用c / c ++编写的自定义库。

所以我为了做到这一点,我需要使用NDK。 该库包含我需要实现的方法,以便访问android

中的特定功能

我的问题是:如何在c中存在的方法中调用我的jni方法 这将调用java方法在android系统中存储会话密钥

所以对于一个实际的例子,因为它可能不清楚:

在一个名为lib_exemple.c的文件中,我有三种方法

第一个是对库的初始化调用(jni到库c) - >工作

JNIEXPORT void JNICALL
Java_com_example_libExemple_Libs_ExempleLib_lib_1Exemple_1init
(JNIEnv *env, jobject instance) {
lib_Example_init('0'); // c func of the library
}

然后第二个是调用java方法的jni(jni到java) - >工作

JNIEXPORT jint
JNICALL  Java_com_example_libExemple_Libs_ExempleLib_lib_1Exemple_1store_1session_1key
    (JNIEnv * env, jobject jobject1, jbyte jbyte1, jchar jchar1, jbyte jbyte2){

jclass clazz = (*env)->FindClass(env, "com/example/libExemple/Libs/ExempleLib");
jmethodID mCurrentActivityId = (*env)->GetMethodID(env, clazz, "KeyStoreSessionKey", "(BCB)I");
jint result = (*env)->CallIntMethod(env, jobject1, mCurrentActivityId, jbyte1, jchar1, jbyte2);

return result;
}

,第三种方法是库c中的方法(库C到jni)

int lib_Exemple_store_session_key(uint8_t Session, P_KEY_ST_T pKey, uint8_t    keyType) {
//i want to call jni func here , so the librairy can access the native android function
return 0;
}

然后在名为ExempleLib.java的文件中配置ndk我已经定义了

static {
System.loadLibrary("LibExemple");
}

然后是库初始化的原型

public native void libExemple_init();

lib_exemple.c中第一个方法的原型

public native int lib_Exemple_store_session_key(byte pKey, char key_length, byte keyIndex);

和它调用的java函数

protected int KeyStoreSessionKey(byte pKey, char key_length, byte keyIndex) {
    ...
}

我的mainActivity包含

ExempleLib LibFunc = new ExempleLib();
Log.d(TAG, "init lib" );
LibFunc.lib_Exemple_init();

我的目标是在初始化我的库并调用init函数之后,它可以调用lib_exemple.c的第二个方法中的第一个方法(库中使用的方法)

感谢

编辑:

我的问题的解决方案是当我初始化lib时,我需要保存jvm 所以我可以直接访问库方法中的JNIenv

jobject Savedinstance = NULL;
static JavaVM *cachedJVM;

JNIEXPORT jint JNICALL JNI_OnLoad(JavaVM *jvm, void *reserved) {
cachedJVM = jvm;
return JNI_VERSION_1_6;
}

JNIEnv *AttachJava() {
    JavaVMAttachArgs args = {JNI_VERSION_1_6, 0, 0};
    JNIEnv *java;
    (*cachedJVM)->AttachCurrentThread(cachedJVM, &java, &args);
    return java;
}

JNIEXPORT jint JNICALL
Java_com_example_vgosselin_libExemple_Libs_ExempleLib_lib_1init(JNIEnv *env,
                                                                                jobject instance) {
Savedinstance = instance;
void *element = 0;
jint result;
result = lib_Exemple_init_();
return result;
}

所以我可以在

中调用java方法
int lib_Exemple_store_session_key(uint8_t Session, P_KEY_ST_T pKey, uint8_t    keyType) {
JNIEnv *NewEnv = AttachJava();
jclass clazz = (*NewEnv)->FindClass(NewEnv,"com/example/vgosselin/libExemple/Libs/ExempleLib");
jmethodID mCurrentActivityId = (*NewEnv)->GetMethodID(NewEnv,clazz,"KeystoreStoreKey","([BCB)I");
jint result;
jbyteArray Data = 0;
jchar Key = 0;
jbyte Type = 0;

result = (*NewEnv)->CallIntMethod(NewEnv, Savedinstance, mCurrentActivityId, Data, Key, Type);
return result;
}

现在我不再需要jni语法中的方法

JNIEXPORT jint JNICALL    Java_com_example_libExemple_Libs_ExempleLib_lib_1Exemple_1store_1session_1key

0 个答案:

没有答案