首页 > 代码库 > javah 生成.h文件时出现的错误
javah 生成.h文件时出现的错误
"Run TestJni1" 或 "Debug TestJni1" 后,"D:\workspace\testjni1\bin\classes\com\example\testjni1" 目錄下會產生很多 *.class 文件,對其中的 "MainActivity.class" 進行如下操作,據說會生成所需頭文件。但實際運作發現不行。
*********************************** 以下是操作過程 ********************************************************
Microsoft Windows [版本 6.1.7601]
版权所有 (c) 2009 Microsoft Corporation。保留所有权利。
C:\Users\Administrator>d:
D:\>cd \workspace\testjni1\bin
D:\workspace\testjni1\bin>javah -d header -classpath classes -jni com.example.testjni1.MainActivity
错误: 无法访问android.app.Activity
找不到android.app.Activity的类文件
*********************************** 以上是操作過程 ********************************************************
據說在 src 目錄下也可以獲得頭文件,我試過了,是可以的。
*********************************** 以下是操作過程 ********************************************************
Microsoft Windows [版本 6.1.7601]
版权所有 (c) 2009 Microsoft Corporation。保留所有权利。
C:\Users\Administrator>d:
D:\>cd \workspace\testjni1\src
D:\workspace\testjni1\src>javah com.example.testjni1.MainActivity
D:\workspace\testjni1\src>dir
驱动器 D 中的卷没有标签。
卷的序列号是 000C-6D9F
D:\workspace\testjni1\src 的目录
2013/03/09 10:57 <DIR> .
2013/03/09 10:57 <DIR> ..
2013/03/09 10:38 <DIR> com
2013/03/09 10:57 726 com_example_testjni1_MainActivity.h
1 个文件 726 字节
3 个目录 10,670,010,368 可用字节
D:\workspace\testjni1\src>
*********************************** 以上是操作過程 ********************************************************
这招其實是對 "D:\workspace\testjni1\src\com.example\testjni1\MainActivity.java" 進行操作,可以在 ‘src‘ 目錄下获得一個 ‘com_example_testjni1_MainActivity.h" 头文件,但是經檢驗這個文件裡面沒多少東西。
最可靠的方法还是为 javah 指明 android.jar 的路徑,會比較好。
*********************************** 以下是操作過程 ********************************************************
Microsoft Windows [版本 6.1.7601]
版权所有 (c) 2009 Microsoft Corporation。保留所有权利。
C:\Users\Administrator>d:
D:\>cd workspace\tstjni1\bin
D:\workspace\testjni1\bin>javah -d heafer -classpath c:\adt-bundle-windows-x86_64\adt-bundle-windows-x86_64-20130219\sdk\platforms\android-17\android.jar;classes -jni com.example.testjni1.MainActivity
D:\workspace\testjni1\bin>dir
驱动器 D 中的卷没有标签。
卷的序列号是 000C-6D9F
D:\workspace\testjni1\bin 的目录
2013/03/09 13:58 <DIR> .
2013/03/09 13:58 <DIR> ..
2013/03/09 13:16 880 AndroidManifest.xml
2013/03/09 13:16 <DIR> classes
2013/03/09 13:33 448,812 classes.dex
2013/03/09 13:58 3,938 com_example_testjni1_MainActivity.h
2013/03/09 13:33 <DIR> dexedLibs
2013/03/09 13:39 <DIR> header
2013/03/09 13:33 196,360 testjni1.apk
2013/03/09 13:33 <DIR> res
2013/03/09 13:33 40,788 resources.ap_
5 个文件 690,778 字节
6 个目录 10,671,005,696 可用字节
D:\workspace\testjni1\bin>
*********************************** 以上是操作過程 ********************************************************
【本人通过上面方法解决了问题,操作如下】********************* START *********************************
Microsoft Windows [版本 6.1.7601]
版权所有 (c) 2009 Microsoft Corporation。保留所有权利。
C:\Users\Administrator>cd..
C:\Users>cd..
C:\>d:
D:\>cd D:\software\adt\android-ndk-r8d\samples\hello-jni
D:\software\adt\android-ndk-r8d\samples\hello-jni>javah -classpath bin/classes;D
:\software\adt\sdk\platforms\android-17\android.jar -d ndk com.example.hellojni.
HelloJni
D:\software\adt\android-ndk-r8d\samples\hello-jni>
************************************** END ************************************************
這次獲得的頭文件裡面內容多了很多。
*********************************** 以下是第一次獲得的頭文件 ******************************************
/* DO NOT EDIT THIS FILE - it is machine generated */
#include <jni.h>
/* Header for class com_example_testjni1_MainActivity */
#ifndef _Included_com_example_testjni1_MainActivity
#define _Included_com_example_testjni1_MainActivity
#ifdef __cplusplus
extern "C" {
#endif
/*
* Class: com_example_testjni1_MainActivity
* Method: add
* Signature: (II)I
*/
JNIEXPORT jint JNICALL Java_com_example_testjni1_MainActivity_add
(JNIEnv *, jobject, jint, jint);
/*
* Class: com_example_testjni1_MainActivity
* Method: sub
* Signature: (II)I
*/
JNIEXPORT jint JNICALL Java_com_example_testjni1_MainActivity_sub
(JNIEnv *, jobject, jint, jint);
#ifdef __cplusplus
}
#endif
#endif
*********************************** 以上是第一次獲得的頭文件 ******************************************
*********************************** 以下是第二次獲得的頭文件 ******************************************
/* DO NOT EDIT THIS FILE - it is machine generated */
#include <jni.h>
/* Header for class com_example_testjni1_MainActivity */
#ifndef _Included_com_example_testjni1_MainActivity
#define _Included_com_example_testjni1_MainActivity
#ifdef __cplusplus
extern "C" {
#endif
#undef com_example_testjni1_MainActivity_MODE_PRIVATE
#define com_example_testjni1_MainActivity_MODE_PRIVATE 0L
#undef com_example_testjni1_MainActivity_MODE_WORLD_READABLE
#define com_example_testjni1_MainActivity_MODE_WORLD_READABLE 1L
#undef com_example_testjni1_MainActivity_MODE_WORLD_WRITEABLE
#define com_example_testjni1_MainActivity_MODE_WORLD_WRITEABLE 2L
#undef com_example_testjni1_MainActivity_MODE_APPEND
#define com_example_testjni1_MainActivity_MODE_APPEND 32768L
#undef com_example_testjni1_MainActivity_MODE_MULTI_PROCESS
#define com_example_testjni1_MainActivity_MODE_MULTI_PROCESS 4L
#undef com_example_testjni1_MainActivity_MODE_ENABLE_WRITE_AHEAD_LOGGING
#define com_example_testjni1_MainActivity_MODE_ENABLE_WRITE_AHEAD_LOGGING 8L
#undef com_example_testjni1_MainActivity_BIND_AUTO_CREATE
#define com_example_testjni1_MainActivity_BIND_AUTO_CREATE 1L
#undef com_example_testjni1_MainActivity_BIND_DEBUG_UNBIND
#define com_example_testjni1_MainActivity_BIND_DEBUG_UNBIND 2L
#undef com_example_testjni1_MainActivity_BIND_NOT_FOREGROUND
#define com_example_testjni1_MainActivity_BIND_NOT_FOREGROUND 4L
#undef com_example_testjni1_MainActivity_BIND_ABOVE_CLIENT
#define com_example_testjni1_MainActivity_BIND_ABOVE_CLIENT 8L
#undef com_example_testjni1_MainActivity_BIND_ALLOW_OOM_MANAGEMENT
#define com_example_testjni1_MainActivity_BIND_ALLOW_OOM_MANAGEMENT 16L
#undef com_example_testjni1_MainActivity_BIND_WAIVE_PRIORITY
#define com_example_testjni1_MainActivity_BIND_WAIVE_PRIORITY 32L
#undef com_example_testjni1_MainActivity_BIND_IMPORTANT
#define com_example_testjni1_MainActivity_BIND_IMPORTANT 64L
#undef com_example_testjni1_MainActivity_BIND_ADJUST_WITH_ACTIVITY
#define com_example_testjni1_MainActivity_BIND_ADJUST_WITH_ACTIVITY 128L
#undef com_example_testjni1_MainActivity_CONTEXT_INCLUDE_CODE
#define com_example_testjni1_MainActivity_CONTEXT_INCLUDE_CODE 1L
#undef com_example_testjni1_MainActivity_CONTEXT_IGNORE_SECURITY
#define com_example_testjni1_MainActivity_CONTEXT_IGNORE_SECURITY 2L
#undef com_example_testjni1_MainActivity_CONTEXT_RESTRICTED
#define com_example_testjni1_MainActivity_CONTEXT_RESTRICTED 4L
#undef com_example_testjni1_MainActivity_RESULT_CANCELED
#define com_example_testjni1_MainActivity_RESULT_CANCELED 0L
#undef com_example_testjni1_MainActivity_RESULT_OK
#define com_example_testjni1_MainActivity_RESULT_OK -1L
#undef com_example_testjni1_MainActivity_RESULT_FIRST_USER
#define com_example_testjni1_MainActivity_RESULT_FIRST_USER 1L
#undef com_example_testjni1_MainActivity_DEFAULT_KEYS_DISABLE
#define com_example_testjni1_MainActivity_DEFAULT_KEYS_DISABLE 0L
#undef com_example_testjni1_MainActivity_DEFAULT_KEYS_DIALER
#define com_example_testjni1_MainActivity_DEFAULT_KEYS_DIALER 1L
#undef com_example_testjni1_MainActivity_DEFAULT_KEYS_SHORTCUT
#define com_example_testjni1_MainActivity_DEFAULT_KEYS_SHORTCUT 2L
#undef com_example_testjni1_MainActivity_DEFAULT_KEYS_SEARCH_LOCAL
#define com_example_testjni1_MainActivity_DEFAULT_KEYS_SEARCH_LOCAL 3L
#undef com_example_testjni1_MainActivity_DEFAULT_KEYS_SEARCH_GLOBAL
#define com_example_testjni1_MainActivity_DEFAULT_KEYS_SEARCH_GLOBAL 4L
/*
* Class: com_example_testjni1_MainActivity
* Method: add
* Signature: (II)I
*/
JNIEXPORT jint JNICALL Java_com_example_testjni1_MainActivity_add
(JNIEnv *, jobject, jint, jint);
/*
* Class: com_example_testjni1_MainActivity
* Method: sub
* Signature: (II)I
*/
JNIEXPORT jint JNICALL Java_com_example_testjni1_MainActivity_sub
(JNIEnv *, jobject, jint, jint);
#ifdef __cplusplus
}
#endif
#endif
*********************************** 以上是第二次獲得的頭文件 ******************************************
两个文件明显很不同,但网上看到,大家一般认为两者无区别。我只能這樣告訴你——不要開玩笑了好嗎?
Android使用NDK开发项目时的一些问题
在使用NDK的过程中,有一个步骤是根据生成的 .class 文件生成相应的 .h 文件。
网上相关文档给出的方式是使用如下命令:
cd <project dir>
mkdir jni
javah -calsspath bin -d jni <class>
即,进入工程目录,创建一个jni的文件夹。
然后调用javah命令通过bin目录下的 .class 文件生成 .h 文件并放到jni文件夹中。
需要注意的是,这里的 <class> 是以 包名.类名 的形式指定的,不能省略包名。
但是,运行后出现如下错误:
错误:无法访问 <class>
未找到 <class> 的类文件
javadoc: 错误 - 找不到类 <class>。
Error: 未在命令行中指定任何类。请尝试使用 -help。
后来发现,生成的 .class 文件并不是直接放到bin文件夹下的,而是包含一个名为classes的子目录。
所以,把以上命令改为:
javah -calsspath bin/classes -d jni <package>.<class>
【本人也出现这个问题,通过上面把 “bin” 修改为 “bin/classes” 解决问题 】
2、
运行后,又出现了以下错误:
错误:无法访问 <class>
错误的类文件: <class file>
类文件具有错误的版本 50.0,应为 49.0
请删除该文件或确保该文件位于正确的类路径子目录中。
com.sun.tools.javac.util.Abort
at com.sun.tools.javac.comp.Check.completionError(Check.java:169)
at com.sun.tools.javadoc.DocEnv.loadClass(DocEnv.java:149)
at com.sun.tools.javadoc.RootDocImpl.<init>(RootDocImpl.java:77)
at com.sun.tools.javadoc.JavadocTool.getRootDocImpl(JavadocTool.java:156)
at com.sun.tools.javadoc.Start.parseAndExecute(Start.java:330)
at com.sun.tools.javadoc.Start.begin(Start.java:128)
at com.sun.tools.javadoc.Main.execute(Main.java:66)
at com.sun.tools.javah.Main.main(Main.java:147)
javadoc: 错误 - 致命错误
这个错误是由于jdk版本不一致造成的。
Eclipse创建 .class文件使用的jdk版本是1.6,而运行javah命令使用的是1.5版本。
修改方法,可以设置Eclipse中的jdk版本,也可以修改系统环境对应的java版本。
总之,使各个命令使用的jdk的版本保持一致即可。
3、
当根据 .h 文件编写好 .c 及 Android.mk 文件之后,需要通过NDK命令编译为 .so 文件。
需要将ndk安装目录添加到环境变量中,然后在jni目录下执行命令 ndk-build 命令。
但是,在 r7 版本下会报以下错误:
<ndk>/prebuilt/linux-x86/bin/awk: 无法执行二进制文件
Android NDK: Host ‘awk‘ tool is outdated. Please define HOST_AWK to ...
<ndk>/build/core/init.mk:258: *** Android NDK: Aborting. 。 停止。
这个错误是因为 ndk 包中的awk命令与我当前系统版本不符。
如果系统本身是存在awk命令的话,只需将 <ndk>/prebuilt/linux-x86/bin/awk 删除或者重命名即可。
4、
如果 .so 文件编译成功,会在项目目录下生成文件夹 libs/armeabi,相应的 .so 文件就在该目录下。
打包APK时,会自动将该目录包含进去,保证程序执行时,能够找到相应的库。
但是,我在运行最终生成的APK时,却出错,提示找不到库:
java.lang.UnsatisfiedLinkError: Couldn‘t load <so>: findLibrary returned null
at java.lang.Runtime.loadLibrary(Runtime.java:429)
at java.lang.System.loadLibrary(System.java:554)
这个错误是因为,库的命名是有规则的。
在Android.mk文件中通过LOCAL_MODULE定义库的名字时,不要加前缀lib和后缀 .so。
在生成 .so 文件时,会自动添加前缀lib和后缀 .so。
在java中调用System.loadLibrary()时,参数与LOCAL_MODULE定义的名字要保持一致。
另外,如果定义LOCAL_MODULE时添加了前缀lib,则在生成 .so 文件时,不会再重复添加前缀lib。
这时候,自动生成的 .so 文件只比定义多了一个后缀 .so。
但是在java中,仍然不要加前缀lib,也就是与LOCAL_MODULE不加前缀时的情形是一样的。
【转自】http://hi.baidu.com/gaogaf/item/c20d5abf1a073b42bb0e1277
【转自】http://blog.163.com/xdma_tw/blog/static/16610932920132910513108/
javah 生成.h文件时出现的错误