0、下载jdk并配置环境变量java
下载最新jdk,百度搜索“jdk”就有了。安装完成后,配置环境变量(网上一搜,一堆,我这里仅做简要叙述)android
系统变量→新建 CLASSPATH 变量c++
变量值填写 .;%JAVA_HOME%\lib;%JAVA_HOME%\lib\tools.jar(注意最前面有一点)eclipse
系统变量→寻找 Path 变量→编辑ide
在变量值最后输入 %JAVA_HOME%\bin;%JAVA_HOME%\jre\bin;函数
(注意原来Path的变量值末尾有没有;号,若是没有,先输入;号再输入上面的代码)
系统变量配置完毕学习
一、官网下载最新的ADT。 解压便可(eclipse最好自带ndk插件)ui
二、官网下载最新的NDK。解压便可(ndkr7以上有自带cygwin)spa
三、eclipse没有自带插件,则下载插件。.net
插件网上有,我做为本身学习,也在百度云共享了一份,下载地址:http://pan.baidu.com/s/1i3xImQp
下载好插件放到eclipse下的plugins文件夹下。重启eclipse。
四、重点开始
eclipse→window→preferences→Android→NDK
配置刚刚下载的ndk的路径
五、新建android 项目
右击→properties→C/C++ Build 。去掉默认的build command
设置成${NDKROOT}/ndk-build.cmd
再到build Variables 点击add。配置如图.name:NDKROOT value:你的ndk路径。点击肯定。
六、项目右键->Android Tools->Add Native Support...,输入.so库名字后点击Finish
七、如今已经能够Build咱们的Jni项目了,选择项目,Project->Build Project,编译咱们的c/c++代码,此时项目结构以下,NDK plugin已经为咱们添加好了include,已经为咱们生成了相应的Android.mk以及 cpp文件。(注意:这里插件为咱们生成的是cpp文件,若你不喜欢能够改回.c,并在mk文件中进行相应更改)
八、能够运行咱们的Jni项目了。
遇到的问题
一、运行c++生成的.so库,若报如下错误:(既找不到函数)
No implementation found for native Lcom/example/hellojni/MainActivity;.stringFromJNI ()Ljava/lang/String;
java.lang.UnsatisfiedLinkError: stringFromJNI
at com.example.hellojni.MainActivity.stringFromJNI(Native Method)
解决方法:
为供Java调用的c++函数前加入extern "C" 修饰,如:(NDK example里面的cpp文件也是这么声明的,参考hello-gl2)
缘由是:
被extern "C"修饰的变量和函数是按照C语言方式编译和链接的。
首先看看C++中对相似C的函数是怎样编译的:做为一种面向对象的语言,C++支持函数重载,而过程式语言C则不支持。函数被C++编译后在符号库中的名字与C语言的不一样。例如,假设某个函数的原型为:void foo( int x, int y );该函数被C编译器编译后在符号库中的名字为_foo,而C++编译器则会产生像_foo_int_int之类的名字(不一样的编译器可能生成的名字不一样,可是都采用了相同的机制,生成的新名字称为“mangled name”)。_foo_int_int这样的名字包含了函数名、函数参数数量及类型信息,C++就是靠这种机制来实现函数重载的。例如,在C++中,函数voidfoo( int x, int y )与void foo( int x, float y )编译生成的符号是不相同的,后者为_foo_int_float。
一样地,C++中的变量除支持局部变量外,还支持类成员变量和全局变量。用户所编写程序的类成员变量可能与全局变量同名,咱们以"."来区分。而本质上,编译器在进行编译时,与函数的处理类似,也为类中的变量取了一个独一无二的名字,这个名字与用户程序中同名的全局变量名字不一样。
所以,若咱们没有使用extern "C"修饰函数,按照C语言方式编译和链接,Jni调用将可能找不到该函数。