NDK环境搭建

http://jingyan.baidu.com/article/3ea51489e7a9bd52e61bbac7.html

http://blog.csdn.net/houshunwei/article/details/17217695

NDK开发:http://blog.csdn.net/ikerpeng/article/details/45393223

http://www.cnblogs.com/devinzhang/archive/2012/02/29/2373729.html


一. Android SDK Android NDK Android Studio 官方下载地址http://www.cnblogs.com/yaotong/archive/2011/01/25/1943615.html



二. 将下载下来的“android-ndk-r10c-windows-x86_64.exe”放到

“D:\Android“目录下面,然后双击安装,便会自动解压到"D:\Android"

下面



三. 选择菜单栏上的[Window->Perferences->Android->NDK]设置 NDK Loaction 为D:\Android\android-ndk-r10c;

android ndk环境配置














四. 设置环境变量。按照这个链接中的引导解决:

  1. 环境变量中新增变量名:NDK_ROOT,变量值:E:\android\android-ndk-r10。Path中添加;%NDK_ROOT%

  2. Head to the project's properties. If you're using Windows, the shortcut is Alt + Enter; or simply right-click the project name to find its properties.

  3. Go to the C/C++ Build section; under Builder Settings tab in Build command: text box you're likely to find something similar to that below, if it's empty then type in the similar text - namely:${NDKROOT}/ndk-build.cmd where NDKROOT, as its name implies, refers to the path where your NDK root folder exists. enter image description here

  4. Now you must inform eclipse what NDKROOT equates to; as in, where is the NDK root path. You can do this by heading to (in your project's properties) C/C++ Build > Environment > press Add…

  5. Now add your environment variable named NDKROOT (the Name) with the relevant path (Value). Note that you're to repeat this per NDK project. You would get a window similar to that below. enter image description here

  6. Press OK to the New variable input window and then OK again to the properties window.

五.  NDK环境基本上已经搭建好,新建一个普通Android项目测试NDK支持。项目右键->Android Tools->Add Native Support...,输入.so库名字后点击Finish

(注意:若项目已经是一个Jni项目,例如NDK example里面的HelloJni,这一步中.so库名字不用填)


六.现在已经可以Build我们的Jni项目了,选择项目,Project->Build Project,编译我们的c/c++代码,此时项目结构如下,NDK plugin已经为我们添加好了include,已经为我们生成了相应的Android.mk以及 cpp文件。(注意:这里插件为我们生成的是cpp文件,若你不喜欢可以改回.c,并在mk文件中进行相应更改)


7、这时,Android NDK环境已经完美搭建好,我们可以在cpp文件中流畅地书写我们的c/c++代码。

(而且当你Alt+/时,已经可以使用自动提示,各种爽歪歪有木有。若你不是用NDK plugin来构建JNI项目,而是选择手动方式,Alt+/是不会提示的


8、关于编译,默认情况下:选择项目,Project->Build Project,来重新编译我们的代码。而且每次run项目的时候,也会自动编译.so库。




一些问题与解决方法:

问题一:Android NDK: WARNING: APP_PLATFORM android-14 is larger than android:minSdkVersion 8 in ./AndroidManifest.xml    (这个是NDK工具的一个BUG,若build Target大于minSdkVersion,则会报这个错误,导致无法运行)
解决方法:
android-ndk-r8e/build/core/add-application.mk第128行把__ndk_warning改为__ndk_info;然后重新build一次项目即可消除错误。
原文:
this problem may be safely fixed by changing this line in add-application.mk from __ndk_warning to __ndk_info
链接:

https://code.google.com/p/android/issues/detail?id=39752



问题二:使用c++来编写本地库,会有一些兼容问题。

(1)直接黏贴HelloJni的stringFromJNI函数过来测试,提示Method 'NewStringUTF' could not be resolved
解决方法

改为:将(*env)->NewStringUTF(env, "Hello from JNI !")改为return env->NewStringUTF("Hello from JNI !")即可

原因是:

NDK plugin默认为我们生成的是cpp文件,而C与C++调用函数的参数不一致,因此找不到函数,具体参考jni.h中的定义。cpp文件中形如(*env)->Method(env, XXX)改成env->Method(XXX)即可。



(2)运行c++生成的.so库,若报以下错误:(既找不到函数)

No implementation found for native Lcom/dgut/android/MainActivity;.stringFromJNI ()Ljava/lang/String;

java.lang.UnsatisfiedLinkError: stringFromJNI

at com.dgut.android.MainActivity.stringFromJNI(Native Method)

解决方法:

为供Java调用的c++函数前加入extern "C" 修饰,如:(NDK example里面的cpp文件也是这么声明的,参考hello-gl2)

[java]  view plain copy
  1. extern "C" {  
  2.     JNIEXPORT jstring JNICALL Java_com_dgut_android_MainActivity_stringFromJNI( JNIEnv* env, jobject thiz );  
  3. }  
  4.   
  5. JNIEXPORT jstring JNICALL Java_com_dgut_android_MainActivity_stringFromJNI( JNIEnv* env, jobject thiz )  
  6. {  
  7.     return env->NewStringUTF("Hello from JNI bear c++");  
  8. }  
原因是:

        被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调用将可能找不到该函数。


还可以在cygwin环境下编译NDK

下载安装cygwin

http://www.cnblogs.com/devinzhang/archive/2012/02/29/2373729.html

  

由于NDK编译代码时必须要用到make和gcc,所以你必须先搭建一个linux环境, cygwin是一个在windows平台上运行的unix模拟环境,它对于学习unix/linux操作环境,或者从unix到windows的应用程序移植,非常有用。通过它,你就可以在不安装linux的情况下使用NDK来编译C、C++代码了。下载地址:http://www.cygwin.com

  1)然后双击运行吧,运行后你将看到安装向导界面。

  2)点击下一步,此时让你选择安装方式:

  • Install from Internet:直接从Internet上下载并立即安装(安装完成后,下载好的安装文件并不会被删除,而是仍然被保留,以便下次再安装)。
  • Download Without Installing:只是将安装文件下载到本地,但暂时不安装。
  • Install from Local Directory:不下载安装文件,直接从本地某个含有安装文件的目录进行安装。

  3)选择第一项,然后点击下一步。

  4)选择要安装的目录,注意,最好不要放到有中文和空格的目录里,似乎会造成安装出问题,其它选项不用变,之后点下一步:

  5)上一步是选择安装cygwin的目录,这个是选择你下载的安装包所在的目录,默认是你运行setup.exe的目录,直接点下一步就可以:

  6)此时你共有三种连接方式选择:

  • Direct Connection:直接连接。
  • Use IE5 Settings:使用IE的连接参数设置进行连接。
  • Use HTTP/FTP Proxy:使用HTTP或FTP代理服务器进行连接(需要输入服务器地址、端口号)。

  用户可根据自己的网络连接的实情情况进行选择,一般正常情况下,均选择第一种,也就是直接连接方式。然后再点击“下一步”。

  7)这是选择要下载的站点,选择后点下一步。

  8)此时会下载加载安装包列表

  9)Search是可以输入你要下载的包的名称,能够快速筛选出你要下载的包。那四个单选按钮是选择下边树的样式,默认就行,不用动。View默认是Category,建议改成full显示全部包再查,省的一些包被隐藏掉。左下角那个复选框是是否隐藏过期包,默认打钩,不用管它就行,下边开始下载我们要安装的包吧,为了避免全部下载,这里列出了后面开发NDK用得着的包:autoconf2.1、automake1.10、binutils、gcc-core、gcc- g++、gcc4-core、gcc4-g++、gdb、pcre、pcre-devel、gawk、make共12个包

  10)然后开始选择安装这些包吧,点skip,把它变成数字版本格式,要确保Bin项变成叉号,而Src项是源码,这个就没必要选了。

  11)下面测试一下cygwin是不是已经安装好了。

      运行cygwin,在弹出的命令行窗口输入:cygcheck -c cygwin命令,会打印出当前cygwin的版本和运行状 态,如果status是ok的话,则cygwin运行正常。

      然后依次输入gcc –version,g++ --version,make –version,gdb –version进行测试,如果都打印出版本信息和一些描述信息,则cygwin安装成功!

3.配置 NDK 环境变量

http://www.cnblogs.com/shangdahao/archive/2013/04/17/3025429.html
新增CYGWIN_HOME键,值为Cygwin的安装目录。在Path末尾增加;%CYGWIN_HOME%\bin

4.用 NDK 来编译程序   

  a.现在我们用安装好的 NDK 来编译一个简单的程序吧,我们选择 ndk 自带的例子 hello-jni ,我的位于E:\android-ndk-r5\samples\hello-jni( 根据你具体的安装位置而定 ) ,

  b.运行 cygwin ,输入命令 cd /cygdrive/e/android-ndk-r5/samples/hello-jni ,进入到 E:\android-ndk-r5\samples\hello-jni 目录。

  c.输入 $NDK/ndk-build ,执行成功后,它会自动生成一个 libs 目录,把编译生成的 .so 文件放在里面。 ($NDK是调用我们之前配置好的环境变量, ndk-build 是调用 ndk 的编译程序 )

  d.此时去 hello-jni 的 libs 目录下看有没有生成的 .so 文件,如果有,你的 ndk 就运行正常啦!




NDK编译第三方库.so

方法一:
http://www.xuebuyuan.com/1449225.html


第一次在Android NDK的C++代码中调用第三方so文件时吃了点亏, 以为只用把.so文件放到libs/armeabi目录下即可, 没想


到一ndk-build, 该so就被删除了, 报告链接错误. 通过了解, 发现NDK下调用.so时需要对其作PREBUILT处理, 步骤如下:


1.在project/jni目录下创建prebuilt子目录(目录名可自定义).
2.将第三方.so放到prebuilt中,并创建Android.mk, 内容如下:
    LOCAL_PATH := $(call my-dir)


    include $(CLEAR_VARS)


    LOCAL_MODULE := xxx


    LOCAL_SRC_FILES := libxxx.so


    include $(PREBUILT_SHARED_LIBRARY)


3.在project/jni/Android.mk中加入
    LOCAL_SHARED_LIBRARIES := xxx


4.在project/jni/android.mk的最后加入
    include $(LOCAL_PATH)/prebuilt/Android.mk


5.运行cygwin, 到project目录下, 运行ndk-build








方法二:只有一个Android.mk文件
http://blog.csdn.net/vrix/article/details/7097794


1.将第三方.so放到project/jni目录下


2.在project/jni/Android.mk中修改
LOCAL_PATH := $(call my-dir)  
  
include $(CLEAR_VARS)  
LOCAL_MODULE := rmdradec
LOCAL_SRC_FILES := librmdradec.so  
include $(PREBUILT_SHARED_LIBRARY)  
  
include $(CLEAR_VARS)  
LOCAL_MODULE := rmDraDecSample
#LOCAL_SHARED_LIBRARY := my-init    #应该用复数形式,否则连接不上第三方库中的函数  
LOCAL_SHARED_LIBRARIES := rmdradec
LOCAL_SRC_FILES := rmDraDecSample.c  
include $(BUILD_EXECUTABLE)  

以上是将NDK编译出来的文件作为可在android上直接运行的可执行文件,所以最后一行是include $(BUILD_EXECUTABLE)  ,如果希望编译出来的是.so文件,改回include $(BUILD_SHARED_LIBRARY)即可。


执行编译出来的可执行文件:

如果是include $(BUILD_EXECUTABLE)编译出来的可执行文件,在android真机上怎么运行,由于我的手机没有root权限,无法运行编译出来的文件,这里用模拟器代替:


a. cmd进入dos窗口

b. 将可执行文件adb push到模拟器

c. adb shell E:\eclipse\workspace\LizmFileExplorer\libs\armeabi\rmDraDecSample /data

d. adb shell E:\eclipse\workspace\LizmFileExplorer\libs\armeabi\librmdradec.so /data

e. #cd /data     进入到文件push到的目录

f. #chmod 777 rmDraDecSample       加入文件权限,否则提示permision dinied

g. #LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/data ./rmDraDecSample  直接./rmDraDecSample会提示CANNOT LINK EXECUTABLE: could not load library "libktest.so" needed by "./testlo

ad"; caused by library "libktest.so" not found,文件运行阶段找不到库,加上LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/data可以解决,/data是执行文件所在的目录。

其他参考网站:
使用NDK生成native C/C++的可执行程序 http://blog.csdn.net/nicebooks/article/details/6601005
android ndk 编译方式,静态库、动态库、可执行文件http://blog.csdn.net/jinliang_890905/article/details/21830351

NDK开发环境搭建  http://zengwu3915.blog.163.com/blog/static/2783489720137252525579/



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值