Android studioでのJNI JAVAとC++の相互調整
3911 ワード
androidでjava呼び出しC++定義インタフェースクラス
Javahコンパイルで対応するCヘッダファイルを生成しますが、この方式は関数名が長すぎるため、一般的に修正してコンパイルするのはあまり好きではありません.紹介しません.ここで紹介するのはJVMの暗黙的な登録、JNI_です.OnLoadとJNI_OnUnload.Android起動時にJNI_が呼び出されますOnLoad関数は、上のインタフェースクラスの2つの関数エントリを登録し、次のように使用します.
package test.simulateapp;
/**
* Created by zhu on 17-6-22.
*/
public class JniInfence {
public static native void init(JNICallJava jniCallJava,String user,String passwd,String addr,int port);
public static native void sendSet(int index,String str,String s);
static {
System.loadLibrary("native-lib");
}
}
Javahコンパイルで対応するCヘッダファイルを生成しますが、この方式は関数名が長すぎるため、一般的に修正してコンパイルするのはあまり好きではありません.紹介しません.ここで紹介するのはJVMの暗黙的な登録、JNI_です.OnLoadとJNI_OnUnload.Android起動時にJNI_が呼び出されますOnLoad関数は、上のインタフェースクラスの2つの関数エントリを登録し、次のように使用します.
jint JNI_OnLoad(JavaVM *vm,void *reserved);
void JNI_OnUnload(JavaVM *vm,void *reserved);
void InitParameter(JavaVM *vm);
void init(JNIEnv *env, jobject,jobject,jstring ip,jstring i,jstring p,jint);//
void send_set(JNIEnv *env, jobject,jint,jstring str,jstring ip);
#define FUNCTIONS (2)
JNINativeMethod ParameterSetFunctions[FUNCTIONS] = {
{ "init","(Ltest/simulateapp/JNICallJava;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;I)V",(void*) init },
{ "sendSet","(ILjava/lang/String;Ljava/lang/String;)V",(void*) send_set },
};
jint JNI_OnLoad(JavaVM *vm,void *reserved)
{
__android_log_print(ANDROID_LOG_ERROR,"JNI_OnLoad","JNI_OnLoad [%d].", __LINE__);
__g_jvm = vm;
InitParameter(__g_jvm);
return JNI_VERSION_1_4;
}
void JNI_OnUnload(JavaVM *vm,void *reserved)
{
__android_log_print(ANDROID_LOG_ERROR,"JNI_OnUnload","JNI [%d].", __LINE__);
}
void InitParameter(JavaVM *vm)
{
JNIEnv* env = 0; // JNIEnv ,
if(vm->GetEnv( (void**)&env, JNI_VERSION_1_4) != JNI_OK) // JavaVM JNIEnv, 1.4
return ;
jclass clazz = env->FindClass( "test/simulateapp/JniInfence"); // , java 。 , native , 。
if(clazz == 0)
{
return ;
}
g_parameter_class = (jclass)env->NewGlobalRef(clazz);
if(env->RegisterNatives( g_parameter_class,ParameterSetFunctions, FUNCTIONS)!= JNI_OK) // , java 。 , !
{
return ;
}
g_server_class = env->FindClass( "test/simulateapp/JNICallJava");
if(g_server_class == 0)
{
return ;
}
g_severeCid = env->GetMethodID(g_server_class, "update_data", "(IILjava/lang/String;I)V");//C JAVA
if (g_severeCid == 0) {
__android_log_print(ANDROID_LOG_ERROR,"Android_Play",
"%s: could not get g_severeCid ID", __FUNCTION__);
}
return;
}
/* C++ JAVA */
void update_data(int index,int cmd,string ss,int strategy_id)
{
if (__g_jvm)
{
bool isAttached = false;
JNIEnv* env = NULL;
if (__g_jvm->GetEnv((void**) &env, JNI_VERSION_1_4) != JNI_OK) {
// try to attach the thread and get the env
// Attach this thread to JVM
jint res = __g_jvm->AttachCurrentThread(&env, NULL);
// Get the JNI env for this thread
if ((res < 0) || !env) {
__android_log_print(ANDROID_LOG_DEBUG,"Android_Play",
"%s: Could not attach thread to JVM (%d, %p)",
__FUNCTION__, res, env);
env = NULL;
} else {
isAttached = true;
}
}
if(env)
{
if (g_severeCid)
{
env->CallVoidMethod((jobject)g_call_java_handler, g_severeCid,index,cmd,env->NewStringUTF(ss.c_str()),strategy_id);
}
}
if (isAttached) {
if (__g_jvm->DetachCurrentThread() < 0) {
}
}
}
return;
}