利用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之后的字符。
相关文章推荐
- windows7下,Java中利用JNI调用c++生成的动态库的使用步骤
- windows7下,Java中利用JNI调用c++生成的动态库的使用步骤
- Ubuntu下,Java中利用JNI调用codeblocks c++生成的动态库的使用步骤
- Ubuntu下,Java中利用JNI调用codeblocks c++生成的动态库的使用步骤
- Ubuntu下,Java中利用JNI调用codeblocks c++生成的动态库的使用步骤
- JNI技术实践小结--原理分析和详细步骤截图说明
- java WebService接口开发注意点 java 利用Xstream生成和解析xml知识结构
- JNI技术实践小结--原理分析和详细步骤截图说明
- Android 利用javah.exe 生成JNI头文件 时的注意事项
- MyEclipse画UML用例图并生成JAVA代码(图文详细步骤)
- 关于如何在docker中利用tomcat和MySQL容器部署java web应用的详细步骤
- JAVA 利用XML生成json完成接口对接实现
- window下利用JNI在java代码中调用c/c++接口
- 【iOS-cocos2d-X 游戏开发之十三】详细讲解在Xcode中利用预编译并通过Jni调用Android的Java层代码(cocos2dx里访问调用Android函数)!
- 利用wsdl文件生成webservice接口的java客户端测试代码
- [置顶] Android 中 c 代码回调Java代码的详细步骤(jni、NDK的使用)
- 【iOS-cocos2d-X 游戏开发之十三】详细讲解在Xcode中利用预编译并通过Jni调用Android的Java层代码(cocos2dx里访问调用Android函数)!
- 在Eclipse里利用javah把java代码声明的JNI方法自动生成成C\C++头文件
- JNI技术实践小结--原理分析和详细步骤截图说明
- 应该如何利用JNI技术提高Java的性能详解