初学JNI,在写HelloWorld的时候遇到的两个问题
(1)无法编译C程序,提示找不到头文件及语法错误
(2)编译成功的dll在Java中调用时报错,找不到方法
经过艰苦卓绝的努力,将解决方案记于此
1、下载eclipse c/cpp(www.eclipse.org)版或安装CDT插件,由于我是直接下载的c版,没有安装过CDT,所以不提供说明
2、安装c/c++编译环境。eclipse本身只是编辑器,语言的编译还是需要编译器自己来做,就像编译Java需要JDK一样。
备选方案有(1)MinGW http://sourceforge.net/projects/mingw/files (2)Cygwin http://www.cygwin.com/(3)VC++。一般来说有VC++或者VS的,就不会用eclipse来开发了,所以这个方案被淘汰了,对于前两个方案,由于eclipse帮助里对MinGW讲解比较清楚,而Cygwin没有将具体怎么用,所以我选择了MinGW。安装的默认路径是C:\MinGW,完整安装占磁盘空间为350MB。
3、设置环境变量,新建环境变量 MINGW_HOME,值为 MinGW的安装路径(默认情况下是C:\MinGW)
4、启动eclipse
5、创建Java项目,建一个类,代码如下
class HelloNative {
public static native void greeting();
}
6、生成C头文件
找到刚刚创建的类的class文件,在命令提示符下运行javah HelloNative
注意,请确认jdk/bin目录是否已经添加到path环境变量下,否则可能提示找不到javah。确认如果提示找不到HelloNative类,请将类所在目录添加到classpath环境变量中。基本上javah和java的用法是一样的。
至此我们已经得到了头文件HelloNative.h。什么,没有?请好好找找。
7、创建C项目
Toolchain(工具链,或者叫工具箱?)选择MinGW GCC,没有的话好好检查一下环境变量。OK,直接Finish就行了。
8、导入JNI
如果这时候把刚刚生成的头文件拷到项目中的话会发现各种错误信息
//(Unresolved inclusion: <jni.h>)
#include <jni.h>
//Syntax error
JNIEXPORT void JNICALL Java_HelloNative_greeting
(JNIEnv *, jclass);
原因是没有导入jni的包(或者库?姑且这么称呼吧,不知道C里头是怎么叫的)
打开项目的Properties(在项目上右键菜单的最后一项)找到C/C++ General -> Paths and Symbols
Configuration中选择[All configurations](选全部,省的一个一个改)。
Includes页签中的Language选择GNU C,单击Add按钮
单击File system...并找到jdk安装目录,选择其下的include目录,然后确定。
先别着急,到这一步结束Unresolved inclusion: <jni.h>的错误提示没有了,但是下面的语法错误还在,原因是找不到jni_md.h。可是奇怪了,jni_md.h明明就在include/win32下啊,怎么说没有呢?
好吧,这个问题纠结了我很久,后来发现不同于java的到一个jar包,会把其中所有的子包都导进去,坑爹的C居然不会自动导入子包...好吧,重复上面步骤,这次导入jdk/include/win32目录。
好了,大功告成。怪了,怎么还有语法错误提示呢?别管他,创建c文件以后错误就消失了。
9、实现C代码
在这之前,先别急着写C代码。首先把HelloNative.h文件打开,在方法名前加一个下划线,如将Java_HelloNative_greeting改为 _Java_HelloNative_greeting
注:这一步至关重要,否则一会儿在Java里找不到本地方法别怪我。
接下来,创建HelloNative.c文件,并将HelloNative.h中的方法签名复制到C文件中,修改成如下格式
// in HelloNative.h
JNIEXPORT void JNICALL _Java_HelloNative_greeting
(JNIEnv *, jclass);
// in HelloNative.c
#include "HelloNative.h"
JNIEXPORT void JNICALL _Java_HelloNative_greeting(JNIEnv *env, jclass cl) {
// 这里是方法实现
printf("Hello World Native\n");
}
(⊙o⊙)… #include 可以用引号包含,也可以用<>包含,两者引用的优先顺序不同,我不是学C的,说不清楚,自己上网查吧。实现完方法,单击工具栏中的锤子图标进行编译,编译通过就OK了。编译分Debug和Release,看有个帖子说Debug模式编译的dll在java中调会报错,我试了一下,发现可以正常运行,但是原则上说,发行版应该比调试版要好的,至少文件更小一些。至于导出的dll叫什么名字就无所谓了,不喜欢可以改的吗,只要在Java中引用的时候用一样的名字就好了。
10、运行测试程序
现在来看看我们的成果吧。将dll拷到java项目的lib目录下(你还有更合适的地方放它吗?)
public class HelloNativeTest {
public static void main(String[] args) {
HelloNative.greeting();
}
static {
System.loadLibrary("HelloNative");
}
}
loadLibrary的参数是dll文件的名字,不包含扩展名
运行前先改一下JVM运行参数Run Configurations -> Arguments -> VM arguments填写
-Djava.library.path=.;./lib
好了,Run一下吧,控制台终于打印出熟悉的“HelloWorld”了,不易啊,泪流满面
- 大小: 38.6 KB
- 大小: 5.6 KB
- 大小: 21.7 KB
- 大小: 7.9 KB
分享到:
相关推荐
在本文中,我们将深入探讨如何在Eclipse集成开发环境中,结合MinGW编译器来构建Java JNI(Java Native Interface)项目。JNI是Java平台的一部分,它允许Java代码和其他语言写的代码进行交互,使得开发者可以利用C/...
#### 五、Eclipse + CDT + MinGW 进行Java调用C/C++ - **安装Eclipse 3.2。** - **安装MinGW:** - 下载并安装。 - 设置环境变量。 - **安装CDT插件:** - 下载并安装。 - **使用CDT:** - 新建C++项目。 - ...
3. **创建JNI工程**:在Eclipse中新建一个C/C++项目,然后根据JNI的要求编写源代码,包括Java和C/C++部分。 4. **生成JNI头文件**:使用`javah`命令(通常在JDK中)从Java类生成C/C++的头文件,这些头文件定义了Java...
JNI是Java平台的一部分,它允许Java代码与其他语言编写的代码进行交互。开发者通常使用JNI与Android的Native Development Kit(NDK)结合,以便利用C、C++等语言实现高性能计算或调用已有的本地库。 描述中的链接...
在编写本地代码前,我们需要生成一个JNI头文件,该文件定义了本地方法的签名。 **命令行操作:** ```bash javah -classpath ./jni/target/classes -d ./jni/jni com.demo.jni.HelloJNI ``` 这将生成一个名为`...
- 将`%MinGW%\bin\mingw32-make.exe`复制并重命名为`make.exe`,便于Eclipse识别。 5. **安装CDT插件**: - 访问[Eclipse CDT官方下载页面](http://www.eclipse.org/cdt/downloads.php),下载CDT插件压缩包。 - ...
5. **安装用于Eclipse纯C++项目编译的工具**(例如Mingw或Cygwin,因为使用ADT提供的编译器可能会导致项目错误,从而无法编译)。 #### 四、注意事项 在整个搭建过程中,需要注意的关键事项包括: - Cocos2dx提供...
在Android开发中,JNI主要用来连接Java代码和C/C++编写的代码。 ##### 2.1 JNI引入 JNI作为一种协议,定义了Java代码如何调用本地C/C++代码的方法,同时也定义了本地C/C++代码如何调用Java代码的方式。通过JNI,...
在开始搭建cocos2d环境之前,我们需要准备好一些工具,包括eclipse、cygwin、NDK、CDT、ADT、CDT等。 cygwin安装配置 首先,我们需要下载setup.exe文件并双击安装。然后,我们需要到Devel Default,选中binutils、...
同时,开发过程中可能需要用到的工具有IDE(如IntelliJ IDEA或Eclipse),编译器(如GCC或MinGW),以及版本控制工具(如Git)。 通过以上步骤,你可以在Java程序中实现对RAR文件的压缩操作。这个过程涉及到了Java...
NDK是Android的本地开发工具包,允许开发者使用C/C++编写代码并生成本地.so库。在这里,我们使用的是android-ndk-r7版本,应将其放在易于访问的路径下。SDK则包含Android开发所需的各种工具和库,你需要自行下载并...