【android】Android新版NDK环境配置(免Cygwin)

2024-06-09 22:38

本文主要是介绍【android】Android新版NDK环境配置(免Cygwin),希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

前言:Android NDK r7及以上的版本已经集成了Cygwin编译环境,也就是说,我们完全可以抛弃庞大的Cygwin了。


r6及以下版本,也可以抛弃几个G的完整版,使用精简过的Mini-Cygwin来编译,解压后大小仅9M,但短小巧精悍,完全可以满足Android NDK的开发。

下载地址:https://code.google.com/p/mini-cygwin/

Eclipse集成Cygwin编译环境可以参考我的这篇贴:http://blog.csdn.net/codezjx/article/details/8858825



下面进入正题,r7及以上版本,跟着我的这篇帖子,完成环境的升级吧!!!

参考官网:http://tools.android.com/recent/usingthendkplugin

1、首先确认自己的ADT版本,NDK plugin的支持是在ADT 20及以后的版本。

2、安装Android Native Development Tools(该组件集成C/C++开发环境),既在安装ADT工具的时候勾选NDK组件,一路next后重启Eclipse使插件生效。


3、下载NDK工具http://developer.android.com/tools/sdk/ndk/index.html,我使用的是最新的android-ndk-r8e-windows-x86.zip,下载完后解压缩。

4、Eclipse -> Window -> Preferences -> Android -> NDK,设置NDK为刚刚解压缩的工具包路径。


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

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


6、现在已经可以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调用将可能找不到该函数。



转自http://blog.csdn.net/codezjx/article/details/8879670



这篇关于【android】Android新版NDK环境配置(免Cygwin)的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1046495

相关文章

MySQL数据库双机热备的配置方法详解

《MySQL数据库双机热备的配置方法详解》在企业级应用中,数据库的高可用性和数据的安全性是至关重要的,MySQL作为最流行的开源关系型数据库管理系统之一,提供了多种方式来实现高可用性,其中双机热备(M... 目录1. 环境准备1.1 安装mysql1.2 配置MySQL1.2.1 主服务器配置1.2.2 从

一篇文章彻底搞懂macOS如何决定java环境

《一篇文章彻底搞懂macOS如何决定java环境》MacOS作为一个功能强大的操作系统,为开发者提供了丰富的开发工具和框架,下面:本文主要介绍macOS如何决定java环境的相关资料,文中通过代码... 目录方法一:使用 which命令方法二:使用 Java_home工具(Apple 官方推荐)那问题来了,

Nginx搭建前端本地预览环境的完整步骤教学

《Nginx搭建前端本地预览环境的完整步骤教学》这篇文章主要为大家详细介绍了Nginx搭建前端本地预览环境的完整步骤教学,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起学习一下... 目录项目目录结构核心配置文件:nginx.conf脚本化操作:nginx.shnpm 脚本集成总结:对前端的意义很多

Linux云服务器手动配置DNS的方法步骤

《Linux云服务器手动配置DNS的方法步骤》在Linux云服务器上手动配置DNS(域名系统)是确保服务器能够正常解析域名的重要步骤,以下是详细的配置方法,包括系统文件的修改和常见问题的解决方案,需要... 目录1. 为什么需要手动配置 DNS?2. 手动配置 DNS 的方法方法 1:修改 /etc/res

mysql8.0.43使用InnoDB Cluster配置主从复制

《mysql8.0.43使用InnoDBCluster配置主从复制》本文主要介绍了mysql8.0.43使用InnoDBCluster配置主从复制,文中通过示例代码介绍的非常详细,对大家的学习或者... 目录1、配置Hosts解析(所有服务器都要执行)2、安装mysql shell(所有服务器都要执行)3、

java程序远程debug原理与配置全过程

《java程序远程debug原理与配置全过程》文章介绍了Java远程调试的JPDA体系,包含JVMTI监控JVM、JDWP传输调试命令、JDI提供调试接口,通过-Xdebug、-Xrunjdwp参数配... 目录背景组成模块间联系IBM对三个模块的详细介绍编程使用总结背景日常工作中,每个程序员都会遇到bu

JDK8(Java Development kit)的安装与配置全过程

《JDK8(JavaDevelopmentkit)的安装与配置全过程》文章简要介绍了Java的核心特点(如跨平台、JVM机制)及JDK/JRE的区别,重点讲解了如何通过配置环境变量(PATH和JA... 目录Java特点JDKJREJDK的下载,安装配置环境变量总结Java特点说起 Java,大家肯定都

linux配置podman阿里云容器镜像加速器详解

《linux配置podman阿里云容器镜像加速器详解》本文指导如何配置Podman使用阿里云容器镜像加速器:登录阿里云获取专属加速地址,修改Podman配置文件并移除https://前缀,最后拉取镜像... 目录1.下载podman2.获取阿里云个人容器镜像加速器地址3.更改podman配置文件4.使用po

Android实现图片浏览功能的示例详解(附带源码)

《Android实现图片浏览功能的示例详解(附带源码)》在许多应用中,都需要展示图片并支持用户进行浏览,本文主要为大家介绍了如何通过Android实现图片浏览功能,感兴趣的小伙伴可以跟随小编一起学习一... 目录一、项目背景详细介绍二、项目需求详细介绍三、相关技术详细介绍四、实现思路详细介绍五、完整实现代码

Vue3 如何通过json配置生成查询表单

《Vue3如何通过json配置生成查询表单》本文给大家介绍Vue3如何通过json配置生成查询表单,本文结合实例代码给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友参考下吧... 目录功能实现背景项目代码案例功能实现背景通过vue3实现后台管理项目一定含有表格功能,通常离不开表单