Android NDK JNI开发<4>

本文介绍了一个JNI跨语言调用的示例程序,包括多个C文件与一个H文件的交互过程。演示了如何从Java调用C函数,并实现字符串转换等功能。

好了,下面的demo程序介绍多个c文件和对应一个h文件的操作方法和步骤:

<1> : 启动eclipse 并且新建一个hellojnidemo4 的android工程,然后将cgywin的编译路径切换到该目录下.

<2> : 还是新建jni目录和配置文件Android.mk和Application.mk等文件

<3> : 先看一下c源代码:

#include "jnia.h"

// java中的jstring, 转化为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); //new   char[alen+1]; "\0"
        memcpy(rtn, ba, alen);
        rtn[alen] = 0;
    }
    (*env)->ReleaseByteArrayElements(env, barr, ba, 0); //释放内存

    return rtn;
}

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

#if defined(__arm__)
#if defined(__ARM_ARCH_7A__)
#if defined(__ARM_NEON__)
#define ABI "armeabi-v7a/NEON"
#else
#define ABI "armeabi-v7a"
#endif
#else
#define ABI "armeabi"
#endif
#elif defined(__i386__)
#define ABI "x86"
#elif defined(__mips__)
#define ABI "mips"
#else
#define ABI "unknown"
#endif

    return (*env)->NewStringUTF(env, "jni message !");

}

JNIEXPORT jint JNICALL
Java_com_example_hellojnidemo4_MainActivity_add(JNIEnv* env, jobject obj,
        jint va, jint vb) {

    return (va + vb);
}

JNIEXPORT jstring JNICALL
Java_com_example_hellojnidemo4_MainActivity_retmessage(JNIEnv* env, jobject obj,
        jstring msg) {

    char* p = Jstring2CStr(env, msg);
    char* newstr = "return string";

    return (*env)->NewStringUTF(env, strcat(p, newstr));

}

对应这个的头文件:

#include<jni.h>
#include<string.h>

#ifndef JNI_HELLO_DEMO_H
#define JNI_HELLO_DEMO_H

#ifdef JNI_C_H
extern "C"{
#endif
JNIEXPORT jstring JNICALL
Java_com_example_hellojnidemo4_MainActivity_showmessage(JNIEnv *,jobject);

JNIEXPORT jint JNICALL
Java_com_example_hellojnidemo4_MainActivity_add(JNIEnv*,jobject,jint,jint);

JNIEXPORT jstring JNICALL
Java_com_example_hellojnidemo4_MainActivity_retmessage(JNIEnv*,jobject,jstring);

#ifdef JNI_C_H
}
#endif

#endif

第二c源文件代码:

#include<jni.h>
#include<string.h>

jint
Java_com_example_hellojnidemo4_MainActivity_dulp(JNIEnv * env,jobject obj,jint va,jint vb){
    if(va>vb){
        return (va-vb);
    }else{
        return (vb-va);
    }
}

下面列出Android.mk如何配置的:

LOCAL_PATH := $(call my-dir)

include $(CLEAR_VARS)

LOCAL_MODULE    := jnilibs
LOCAL_SRC_FILES := jnia.c
LOCAL_SRC_FILES := jnib.c

include $(BUILD_SHARED_LIBRARY)

Application.mk参看前面的.

<4> : 然后直接使用cgywin编译,输入:$NDK/ndk-build

 

<5> : 然后写android部分:添加四个按钮

package com.example.hellojnidemo4;

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

public class MainActivity extends Activity {

    private Button mShowBtn;
    private Button mShowretBtn;
    private Button mAddBtn;
    private Button mDulpBtn;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        mShowBtn = (Button) findViewById(R.id.button1);
        mShowBtn.setOnClickListener(new OnClickListener() {

            @Override
            public void onClick(View arg0) {
                // TODO Auto-generated method stub
                Toast.makeText(MainActivity.this, "message : " + showmessage(),
                        Toast.LENGTH_SHORT).show();
            }

        });

        mShowretBtn = (Button) findViewById(R.id.button2);
        mShowretBtn.setOnClickListener(new OnClickListener() {

            @Override
            public void onClick(View v) {
                // TODO Auto-generated method stub
                Toast.makeText(MainActivity.this, "sum : " + add(12, 11),
                        Toast.LENGTH_SHORT).show();
            }

        });

        mAddBtn = (Button) findViewById(R.id.button3);
        mAddBtn.setOnClickListener(new OnClickListener() {

            @Override
            public void onClick(View v) {
                // TODO Auto-generated method stub
                Toast.makeText(MainActivity.this,
                        "return message : " + retmessage("english"),
                        Toast.LENGTH_SHORT).show();
            }

        });
        
        mDulpBtn=(Button)findViewById(R.id.button4);
        mDulpBtn.setOnClickListener(new OnClickListener(){

            @Override
            public void onClick(View v) {
                // TODO Auto-generated method stub
                Toast.makeText(MainActivity.this, "dulp : "+dulp(10,23), Toast.LENGTH_SHORT).show();
            }
            
        });
    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        // Inflate the menu; this adds items to the action bar if it is present.
        getMenuInflater().inflate(R.menu.main, menu);
        return true;
    }

    private native String showmessage();

    private native int add(int a, int b);
    
    private native int dulp(int a,int b);

    private native String retmessage(String msg);

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

}

<6> :直接运行即可以了.

 

 

 

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值