您的位置:首页 > 编程语言 > Java开发

利用javah技术生成jni接口的详细步骤

2012-09-05 20:44 344 查看

步骤一:创建工程

Location: D:\java\NDK\android-ndk-r8b\MyPro,该路径是NDK的目录,MyPro是自己建立的文件夹。此时D:\java\NDK\android-ndk-r8b\MyPro\JNIMySecond\bin目录下为空





步骤二:创建Jni.class文件





步骤三:Jni.class文件的内容



步骤四:编译Jni.class文件

编译时可以采用以下方式:

第一种方式:运行整个工程,运行完成后,D:\java\NDK\android-ndk-r8b\MyPro\JNIMySecond\bin目录就由以前的空目录变成以下内容



此时在D:\java\NDK\android-ndk-r8b\MyPro\JNIMySecond\bin\com\xxj\JNIMySecond目录下会有一个Jni.class文件



第二种方式:用Project->clean方法,OK之后会进行编译,出现第一种方式完成一样的结论



步骤五:生成.h文件

用cmd打开命令提示符(也可以用Cygwin执行相同的操作),定位到D:\java\NDK\android-ndk-r8b\MyPro\JNIMySecond\bin目录下,输入命令javah –jni com.xxj.JNIMySecond.Jni,如下图所示



命令执行完毕,会在D:\java\NDK\android-ndk-r8b\MyPro\JNIMySecond\bin目录下添加一个com_xxj_JNIMySecond_Jni.h文件,如下图所示



注意:在使用javah –jni com.xxj.JNIMySecond.Jni命令时若出现错误,请检查jdk的环境配置

我的配置为:





变量值为:.;%JAVA_HOME%\lib



变量值为:.;%JAVA_HOME%\bin

打开.h文件,其内容如下:

/* DO NOT EDIT THIS FILE - it is machine generated */

#include <jni.h>

/* Header for class com_xxj_JNIMySecond_Jni */

#ifndef _Included_com_xxj_JNIMySecond_Jni

#define _Included_com_xxj_JNIMySecond_Jni

#ifdef __cplusplus

extern "C" {

#endif

/*

* Class: com_xxj_JNIMySecond_Jni

* Method: stringFromJNI

* Signature: ()Ljava/lang/String;

*/

JNIEXPORT jstring JNICALL Java_com_xxj_JNIMySecond_Jni_stringFromJNI

(JNIEnv *, jclass);

/*

* Class: com_xxj_JNIMySecond_Jni

* Method: stringFromJNIOne

* Signature: ()Ljava/lang/String;

*/

JNIEXPORT jstring JNICALL Java_com_xxj_JNIMySecond_Jni_stringFromJNIOne

(JNIEnv *, jclass);

/*

* Class: com_xxj_JNIMySecond_Jni

* Method: add

* Signature: (II)I

*/

JNIEXPORT jint JNICALL Java_com_xxj_JNIMySecond_Jni_add

(JNIEnv *, jclass, jint, jint);

#ifdef __cplusplus

}

#endif

#endif

根据提示情况对.h文件进行一定程度的修正。我在弄这个工程时,未改动的.h文件会出现Syntax error错误



改正的方法是将JNIEXPORT和JNICALL两个关键字去掉,就OK



对应的在后面的.c文件中函数名就使用jint Java_com_xxj_JNIMySecond_Jni_add

(JNIEnv *, jclass, jint, jint);

步骤六:创建jni文件夹

在工程的根目录D:\java\NDK\android-ndk-r8b\MyPro\JNIMySecond下创建jni文件夹,如图:



将步骤五生成的com_xxj_JNIMySecond_Jni.h文件剪切到jni目录下,同时在jni目录下创建一个与com_xxj_JNIMySecond_Jni.h同名的com_xxj_JNIMySecond_Jni.c文件。在.c文件中实现Jni,java里声明但未实现的本地方法。



com_xxj_JNIMySecond_Jni.c的内容如下

#include "com_xxj_JNIMySecond_Jni.h"

#include <string.h>

/*

* Class: com_xxj_JNIMySecond_Jni

* Method: stringFromJNI

* Signature: ()Ljava/lang/String;

*/

JNIEXPORT jstring JNICALL Java_com_xxj_JNIMySecond_Jni_stringFromJNI

(JNIEnv *, jclass){

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

}

/*

* Class: com_xxj_JNIMySecond_Jni

* Method: stringFromJNIOne

* Signature: ()Ljava/lang/String;

*/

JNIEXPORT jstring JNICALL Java_com_xxj_JNIMySecond_Jni_stringFromJNIOne

(JNIEnv *, jclass){

return (*env)->NewStringUTF(env, "Oh, No !");

}

/*

* Class: com_xxj_JNIMySecond_Jni

* Method: add

* Signature: (II)I

*/

JNIEXPORT jint JNICALL Java_com_xxj_JNIMySecond_Jni_add

(JNIEnv *, jclass, jint, jint){

return x+y;

}

在jni目录下创建一个文件,名字为Android.mk,如下图所示



Android.mk文件的内容为:

# Copyright (C) 2009 The Android Open Source Project

#

# Licensed under the Apache License, Version 2.0 (the "License");

# you may not use this file except in compliance with the License.

# You may obtain a copy of the License at

#

# http://www.apache.org/licenses/LICENSE-2.0
#

# Unless required by applicable law or agreed to in writing, software

# distributed under the License is distributed on an "AS IS" BASIS,

# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.

# See the License for the specific language governing permissions and

# limitations under the License.

#

LOCAL_PATH := $(call my-dir)

include $(CLEAR_VARS)

LOCAL_MODULE := JNIMySecond

LOCAL_SRC_FILES := com_xxj_JNIMySecond_Jni.c

include $(BUILD_SHARED_LIBRARY)

步骤七:生成函数库

在没有操作之前先来看一下D:\java\NDK\android-ndk-r8b\MyPro\JNIMySecond目录当前情况下的内容



打开



,定位到D:\java\NDK\android-ndk-r8b\MyPro\JNIMySecond目录下,输入$NDK/ndk-build命令,如下图



此时,D:\java\NDK\android-ndk-r8b\MyPro\JNIMySecond目录下增加了两个文件夹,libs和obj,如下图



libs文件夹的



就是生成的函数库

步骤八:调用函数库

首先将步骤三中的System.loadLibrary("JNIMy");更改为System.loadLibrary("JNIMySecond");导入的库的名字是libs文件夹下的去掉lib的.so文件的名字。与普通的Java函数调用方法相同如:

package com.xxj.JNIMySecond;

import android.app.Activity;

import android.os.Bundle;

public class JNIMySecond extends Activity {

/** Called when the activity is first created. */

@Override

public void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);

// setContentView(R.layout.main);

System.out.println(Jni.stringFromJNI());

System.out.println(Jni.stringFromJNIOne());

}

}

注意:如果此时没有打印出正确结构,请检查步骤三中System.loadLibrary("JNIMySecond");中是否为libs文件夹下的函数库,该名字是去掉了lib与.so之后的字符。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐