jni使用基础(七)之java调用c事例Demo-阿里云开发者社区

开发者社区> 开发与运维> 正文
登录阅读全文

jni使用基础(七)之java调用c事例Demo

简介:

 

 

1.界面:

package com.devchina.ndk3;

import android.app.Activity;
import android.os.Bundle;
import android.view.View;
import android.widget.Toast;

public class DemoActivity extends Activity {

	static{
		System.loadLibrary("devchina");
	}
	
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
    }
    
    public void passInt(View view){
    	JniProvider jni = new JniProvider();
    	int res = jni.add(3, 5);
    	Toast.makeText(this, res+"", 1).show();
    }
    
    public void passString(View view){
    	JniProvider jni = new JniProvider();
    	String res = jni.sayHelloInc("li si");
    	Toast.makeText(this, res+"", 1).show();
    }
    
    public void passIntArr(View view){
    	int [] arr = {1,2,3,4,5,6};
    	JniProvider jni = new JniProvider();
    	int [] cArr = jni.intMethod(arr);
    	for(int i=0;i<arr.length;i++){
    		System.out.println("java arr["+i+"]="+arr[i]);
    	}
    	
    	for(int j=0;j<cArr.length;j++){
    		System.out.println("c arr["+j+"]="+cArr[j]);
    	}
    	
    	
    }
    
}


 

 

2.jni native类

 

package com.devchina.ndk3;

public class JniProvider {
	
	//在c代码中做加法运算
	public native int add(int x,int y);
	//把字符串传给c处理
	public native String sayHelloInc(String s);
	//把java中的数据组c处理
	public native int[] intMethod(int[] iNum);

}


 

3.Android.mk文件

LOCAL_PATH := $(call my-dir)
 
include $(CLEAR_VARS) 
 
LOCAL_MODULE    :=devchina
LOCAL_SRC_FILES :=devchina.c

LOCAL_LDLIBS += -llog
 
include $(BUILD_SHARED_LIBRARY)


 

 

4.通过javah生成的.h头文件

/* DO NOT EDIT THIS FILE - it is machine generated */
#include <jni.h>
/* Header for class com_devchina_ndk3_JniProvider */

#ifndef _Included_com_devchina_ndk3_JniProvider
#define _Included_com_devchina_ndk3_JniProvider
#ifdef __cplusplus
extern "C" {
#endif
/*
 * Class:     com_devchina_ndk3_JniProvider
 * Method:    add
 * Signature: (II)I
 */
JNIEXPORT jint JNICALL Java_com_devchina_ndk3_JniProvider_add
  (JNIEnv *, jobject, jint, jint);

/*
 * Class:     com_devchina_ndk3_JniProvider
 * Method:    sayHelloInc
 * Signature: (Ljava/lang/String;)Ljava/lang/String;
 */
JNIEXPORT jstring JNICALL Java_com_devchina_ndk3_JniProvider_sayHelloInc
  (JNIEnv *, jobject, jstring);

/*
 * Class:     com_devchina_ndk3_JniProvider
 * Method:    intMethod
 * Signature: ([I)[I
 */
JNIEXPORT jintArray JNICALL Java_com_devchina_ndk3_JniProvider_intMethod
  (JNIEnv *, jobject, jintArray);

#ifdef __cplusplus
}
#endif
#endif


 

 

5.c程序

#include<stdio.h>
#include<jni.h>
#include"com_devchina_ndk3_JniProvider.h"
#include <android/log.h>
#define LOG_TAG "Hello TAG"
#define LOGD(...) __android_log_print(ANDROID_LOG_DEBUG, LOG_TAG, __VA_ARGS__)
#define LOGI(...) __android_log_print(ANDROID_LOG_INFO, LOG_TAG, __VA_ARGS__)

//把java中的String轉化成c語言中的數組
char*   Jstring2CStr(JNIEnv*   env,   jstring   jstr)
{
	 char*   rtn   =   NULL;
	 jclass   clsstring   =   (*env)->FindClass(env,"java/lang/String");
	 jstring   strencode   =   (*env)->NewStringUTF(env,"GB2312");
	 jmethodID   mid   =   (*env)->GetMethodID(env,clsstring,   "getBytes",   "(Ljava/lang/String;)[B");
	 jbyteArray   barr=   (jbyteArray)(*env)->CallObjectMethod(env,jstr,mid,strencode); // String .getByte("GB2312");
	 jsize   alen   =   (*env)->GetArrayLength(env,barr);
	 jbyte*   ba   =   (*env)->GetByteArrayElements(env,barr,JNI_FALSE);
	 if(alen   >   0)
	 {
	  rtn   =   (char*)malloc(alen+1);         //"\0"
	  memcpy(rtn,ba,alen);
	  rtn[alen]=0;
	 }
	 (*env)->ReleaseByteArrayElements(env,barr,ba,0);  //
	 return rtn;
}



JNIEXPORT jint JNICALL Java_com_devchina_ndk3_JniProvider_add
  (JNIEnv * env, jobject obj, jint x, jint y){
   LOGI("x = %d,y=%d",x,y);
   return x+y;
}

JNIEXPORT jstring JNICALL Java_com_devchina_ndk3_JniProvider_sayHelloInc
  (JNIEnv * env, jobject obj, jstring jstr){

	char* p = Jstring2CStr(env,jstr);//在堆空间中,长度可变
    LOGI("in c code %s",p);
    char* newstr = " ni hao ";//在栈空间中,长度不可变了
    //字條串連接操作 stracat(dest,source);
    //要求目标的大小是可变的
    return (*env)->NewStringUTF(env,strcat(p,newstr));

}

JNIEXPORT jintArray JNICALL Java_com_devchina_ndk3_JniProvider_intMethod
  (JNIEnv * env, jobject obj, jintArray jArr){
	int len = (*env)->GetArrayLength(env,jArr);
	LOGI("len=%d",len);

	jint* arr = (*env)->GetIntArrayElements(env,jArr,0);//0,不允许拷贝,1,允许拷贝
	int i=0;
	int temp;
	for(;i<len;i++){
		LOGI("arr[%d]=%d",i,*(arr+i));
		//*(arr+i) +=10;
		temp = arr[i]+20;
		(*env)->SetIntArrayRegion(env,jArr,i,1,&temp);
	}
	//释放内存空间
	(*env)->ReleaseIntArrayElements(env,jArr,arr,0);
	return jArr;
}


 

 

6.界面xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:orientation="vertical" >

    <Button
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="加法" 
        android:onClick="passInt"/>
    
     <Button
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="字符串拼接" 
        android:onClick="passString"/>
     
      <Button
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="传递intArr" 
        android:onClick="passIntArr"/>

</LinearLayout>


 

 

 代码下载:http://download.csdn.net/detail/hudan2714/4327239

 

 

版权声明:本文内容由阿里云实名注册用户自发贡献,版权归原作者所有,阿里云开发者社区不拥有其著作权,亦不承担相应法律责任。具体规则请查看《阿里云开发者社区用户服务协议》和《阿里云开发者社区知识产权保护指引》。如果您发现本社区中有涉嫌抄袭的内容,填写侵权投诉表单进行举报,一经查实,本社区将立刻删除涉嫌侵权内容。

分享:
开发与运维
使用钉钉扫一扫加入圈子
+ 订阅

集结各类场景实战经验,助你开发运维畅行无忧

其他文章
最新文章
相关文章