﻿<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/"><channel><title>C++博客-多一分钟学习，早一秒钟提高-随笔分类-Android</title><link>http://www.cppblog.com/xkjy3000/category/20738.html</link><description>VC++、C++、Socket、DirectUI、wxWidgets、Android、IOS</description><language>zh-cn</language><lastBuildDate>Sun, 24 Nov 2013 05:06:16 GMT</lastBuildDate><pubDate>Sun, 24 Nov 2013 05:06:16 GMT</pubDate><ttl>60</ttl><item><title>Android使用JNI实现Java与C之间传递数据</title><link>http://www.cppblog.com/xkjy3000/archive/2013/11/24/204416.html</link><dc:creator>虚空骄阳</dc:creator><author>虚空骄阳</author><pubDate>Sun, 24 Nov 2013 05:04:00 GMT</pubDate><guid>http://www.cppblog.com/xkjy3000/archive/2013/11/24/204416.html</guid><wfw:comment>http://www.cppblog.com/xkjy3000/comments/204416.html</wfw:comment><comments>http://www.cppblog.com/xkjy3000/archive/2013/11/24/204416.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/xkjy3000/comments/commentRss/204416.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/xkjy3000/services/trackbacks/204416.html</trackback:ping><description><![CDATA[<span style="line-height: 31px; color: #333333; font-family: 'Hiragino Sans GB W3', 'Hiragino Sans GB', Arial, Helvetica, simsun, u5b8bu4f53; background-color: #ffffff; font-size: 18px;">介绍Java如何将数据传递给C和C回调Java的方法。&nbsp; java传递数据给C，在C代码中进行处理数据，处理完数据后返回给java。C的回调是Java传递数据给C，C需要用到Java中的某个方法，就需要调用java的方法。</span><p style="line-height: 28px; margin: 0px 0px 10px; padding: 0px; color: #333333; font-family: 'Hiragino Sans GB W3', 'Hiragino Sans GB', Arial, Helvetica, simsun, u5b8bu4f53; font-size: 16px; background-color: #ffffff;"><span style="line-height: 31px; font-size: 18px;">Android中使用JNI七个步骤:</span></p><p style="line-height: 28px; margin: 0px 0px 10px; padding: 0px; color: #333333; font-family: 'Hiragino Sans GB W3', 'Hiragino Sans GB', Arial, Helvetica, simsun, u5b8bu4f53; font-size: 16px; background-color: #ffffff;">1.创建一个android工程</p><p style="line-height: 28px; margin: 0px 0px 10px; padding: 0px; color: #333333; font-family: 'Hiragino Sans GB W3', 'Hiragino Sans GB', Arial, Helvetica, simsun, u5b8bu4f53; font-size: 16px; background-color: #ffffff;">2.JAVA代码中写声明native 方法 public native String helloFromJNI();</p><p style="line-height: 28px; margin: 0px 0px 10px; padding: 0px; color: #333333; font-family: 'Hiragino Sans GB W3', 'Hiragino Sans GB', Arial, Helvetica, simsun, u5b8bu4f53; font-size: 16px; background-color: #ffffff;">3.用javah工具生成头文件</p><p style="line-height: 28px; margin: 0px 0px 10px; padding: 0px; color: #333333; font-family: 'Hiragino Sans GB W3', 'Hiragino Sans GB', Arial, Helvetica, simsun, u5b8bu4f53; font-size: 16px; background-color: #ffffff;">4. 创建jni目录,引入头文件,根据头文件实现c代码</p><p style="line-height: 28px; margin: 0px 0px 10px; padding: 0px; color: #333333; font-family: 'Hiragino Sans GB W3', 'Hiragino Sans GB', Arial, Helvetica, simsun, u5b8bu4f53; font-size: 16px; background-color: #ffffff;">5.编写Android.mk文件</p><p style="line-height: 28px; margin: 0px 0px 10px; padding: 0px; color: #333333; font-family: 'Hiragino Sans GB W3', 'Hiragino Sans GB', Arial, Helvetica, simsun, u5b8bu4f53; font-size: 16px; background-color: #ffffff;">6.Ndk编译生成动态库</p><p style="line-height: 28px; margin: 0px 0px 10px; padding: 0px; color: #333333; font-family: 'Hiragino Sans GB W3', 'Hiragino Sans GB', Arial, Helvetica, simsun, u5b8bu4f53; font-size: 16px; background-color: #ffffff;">7.Java代码load 动态库.调用native代码</p><p style="line-height: 28px; margin: 0px 0px 10px; padding: 0px; color: #333333; font-family: 'Hiragino Sans GB W3', 'Hiragino Sans GB', Arial, Helvetica, simsun, u5b8bu4f53; font-size: 16px; background-color: #ffffff;"><span style="line-height: 31px; font-size: 18px;"><strong>Java调用C进行数据传递</strong></span></p><p style="line-height: 28px; margin: 0px 0px 10px; padding: 0px; color: #333333; font-family: 'Hiragino Sans GB W3', 'Hiragino Sans GB', Arial, Helvetica, simsun, u5b8bu4f53; font-size: 16px; background-color: #ffffff;">&nbsp;这里分别传递整形、字符串、数组在C中进行处理。</p><p style="line-height: 28px; margin: 0px 0px 10px; padding: 0px; color: #333333; font-family: 'Hiragino Sans GB W3', 'Hiragino Sans GB', Arial, Helvetica, simsun, u5b8bu4f53; font-size: 16px; background-color: #ffffff;"><strong>声明native 方法：</strong></p><div style="line-height: 28px; color: #333333; font-family: 'Hiragino Sans GB W3', 'Hiragino Sans GB', Arial, Helvetica, simsun, u5b8bu4f53; font-size: 16px; background-color: #ffffff;"><div><strong>[java]</strong>&nbsp;<a title="view plain" rel="nofollow" href="http://blog.csdn.net/furongkang/article/details/6857610#" style="text-decoration: none; color: #556c88;">view plain</a><a title="copy" rel="nofollow" href="http://blog.csdn.net/furongkang/article/details/6857610#" style="text-decoration: none; color: #556c88;">copy</a></div><ol start="1" style="margin: 5px 0px 5px 40px; padding: 0px;"><li>public&nbsp;class&nbsp;DataProvider&nbsp;{&nbsp;&nbsp;</li><li>&nbsp;&nbsp;&nbsp;&nbsp;//&nbsp;两个java中的int&nbsp;传递c&nbsp;语言&nbsp;,&nbsp;&nbsp;c语言处理这个相加的逻辑,把相加的结果返回给java&nbsp;&nbsp;</li><li>&nbsp;&nbsp;&nbsp;&nbsp;public&nbsp;native&nbsp;int&nbsp;add(int&nbsp;x&nbsp;,int&nbsp;y);&nbsp;&nbsp;</li><li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</li><li>&nbsp;&nbsp;&nbsp;&nbsp;//把一个java中的字符串传递给c语言,&nbsp;c&nbsp;语言处理下字符串,&nbsp;处理完毕返回给java&nbsp;&nbsp;&nbsp;</li><li>&nbsp;&nbsp;&nbsp;&nbsp;public&nbsp;native&nbsp;String&nbsp;sayHelloInC(String&nbsp;s);&nbsp;&nbsp;</li><li>&nbsp;&nbsp;</li><li>&nbsp;&nbsp;&nbsp;&nbsp;//把一个java中int类型的数组传递给c语言,&nbsp;c语言里面把数组的每一个元素的值&nbsp;都增加5,&nbsp;&nbsp;&nbsp;</li><li>&nbsp;&nbsp;&nbsp;&nbsp;//然后在把处理完毕的数组，返回给java&nbsp;&nbsp;</li><li>&nbsp;&nbsp;&nbsp;&nbsp;public&nbsp;native&nbsp;int[]&nbsp;intMethod(int[]&nbsp;iNum);&nbsp;&nbsp;&nbsp;</li><li>}&nbsp;&nbsp;</li></ol></div><p style="line-height: 28px; margin: 0px 0px 10px; padding: 0px; color: #333333; font-family: 'Hiragino Sans GB W3', 'Hiragino Sans GB', Arial, Helvetica, simsun, u5b8bu4f53; font-size: 16px; background-color: #ffffff;"><br /><strong>以上方法要在C中实现的头文件，头文件可以理解为要在C中实现的方法</strong></p><p style="line-height: 28px; margin: 0px 0px 10px; padding: 0px; color: #333333; font-family: 'Hiragino Sans GB W3', 'Hiragino Sans GB', Arial, Helvetica, simsun, u5b8bu4f53; font-size: 16px; background-color: #ffffff;"><strong>其中 JENEnv* 代表的是java环境 , 通过这个环境可以调用java的方法，jobject 表示哪个对象调用了 这个c语言的方法, thiz就表示的是当前的对象</strong></p><div style="line-height: 28px; color: #333333; font-family: 'Hiragino Sans GB W3', 'Hiragino Sans GB', Arial, Helvetica, simsun, u5b8bu4f53; font-size: 16px; background-color: #ffffff;"><div><strong>[cpp]</strong>&nbsp;<a title="view plain" rel="nofollow" href="http://blog.csdn.net/furongkang/article/details/6857610#" style="text-decoration: none; color: #556c88;">view plain</a><a title="copy" rel="nofollow" href="http://blog.csdn.net/furongkang/article/details/6857610#" style="text-decoration: none; color: #556c88;">copy</a></div><ol start="1" style="margin: 5px 0px 5px 40px; padding: 0px;"><li>/*&nbsp;DO&nbsp;NOT&nbsp;EDIT&nbsp;THIS&nbsp;FILE&nbsp;-&nbsp;it&nbsp;is&nbsp;machine&nbsp;generated&nbsp;*/&nbsp;&nbsp;</li><li>#include&nbsp;&lt;jni.h&gt;&nbsp;&nbsp;</li><li>/*&nbsp;Header&nbsp;for&nbsp;class&nbsp;cn_itcast_ndk3_DataProvider&nbsp;*/&nbsp;&nbsp;</li><li>&nbsp;&nbsp;</li><li>#ifndef&nbsp;_Included_cn_itcast_ndk3_DataProvider&nbsp;&nbsp;</li><li>#define&nbsp;_Included_cn_itcast_ndk3_DataProvider&nbsp;&nbsp;</li><li>#ifdef&nbsp;__cplusplus&nbsp;&nbsp;</li><li>extern&nbsp;"C"&nbsp;{&nbsp;&nbsp;</li><li>#endif&nbsp;&nbsp;</li><li>/*&nbsp;</li><li>&nbsp;*&nbsp;Class:&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;cn_itcast_ndk3_DataProvider&nbsp;</li><li>&nbsp;*&nbsp;Method:&nbsp;&nbsp;&nbsp;&nbsp;add&nbsp;</li><li>&nbsp;*&nbsp;Signature:&nbsp;(II)I&nbsp;</li><li>&nbsp;*/&nbsp;&nbsp;</li><li>JNIEXPORT&nbsp;jint&nbsp;JNICALL&nbsp;Java_cn_itcast_ndk3_DataProvider_add&nbsp;&nbsp;</li><li>&nbsp;&nbsp;(JNIEnv&nbsp;*,&nbsp;jobject,&nbsp;jint,&nbsp;jint);&nbsp;&nbsp;</li><li>&nbsp;&nbsp;</li><li>/*&nbsp;</li><li>&nbsp;*&nbsp;Class:&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;cn_itcast_ndk3_DataProvider&nbsp;</li><li>&nbsp;*&nbsp;Method:&nbsp;&nbsp;&nbsp;&nbsp;sayHelloInC&nbsp;</li><li>&nbsp;*&nbsp;Signature:&nbsp;(Ljava/lang/String;)Ljava/lang/String;&nbsp;</li><li>&nbsp;*/&nbsp;&nbsp;</li><li>JNIEXPORT&nbsp;jstring&nbsp;JNICALL&nbsp;Java_cn_itcast_ndk3_DataProvider_sayHelloInC&nbsp;&nbsp;</li><li>&nbsp;&nbsp;(JNIEnv&nbsp;*,&nbsp;jobject,&nbsp;jstring);&nbsp;&nbsp;</li><li>&nbsp;&nbsp;</li><li>/*&nbsp;</li><li>&nbsp;*&nbsp;Class:&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;cn_itcast_ndk3_DataProvider&nbsp;</li><li>&nbsp;*&nbsp;Method:&nbsp;&nbsp;&nbsp;&nbsp;intMethod&nbsp;</li><li>&nbsp;*&nbsp;Signature:&nbsp;([I)[I&nbsp;</li><li>&nbsp;*/&nbsp;&nbsp;</li><li>JNIEXPORT&nbsp;jintArray&nbsp;JNICALL&nbsp;Java_cn_itcast_ndk3_DataProvider_intMethod&nbsp;&nbsp;</li><li>&nbsp;&nbsp;(JNIEnv&nbsp;*,&nbsp;jobject,&nbsp;jintArray);&nbsp;&nbsp;</li><li>&nbsp;&nbsp;</li><li>#ifdef&nbsp;__cplusplus&nbsp;&nbsp;</li><li>}&nbsp;&nbsp;</li><li>#endif&nbsp;&nbsp;</li><li>#endif&nbsp;&nbsp;</li></ol></div><p style="line-height: 28px; margin: 0px 0px 10px; padding: 0px; color: #333333; font-family: 'Hiragino Sans GB W3', 'Hiragino Sans GB', Arial, Helvetica, simsun, u5b8bu4f53; font-size: 16px; background-color: #ffffff;"><br /><strong>C代码出了要引用头文件外，还要引入日志信息，以方便在C 中进行调试</strong></p><div style="line-height: 28px; color: #333333; font-family: 'Hiragino Sans GB W3', 'Hiragino Sans GB', Arial, Helvetica, simsun, u5b8bu4f53; font-size: 16px; background-color: #ffffff;"><div><strong>[cpp]</strong>&nbsp;<a title="view plain" rel="nofollow" href="http://blog.csdn.net/furongkang/article/details/6857610#" style="text-decoration: none; color: #556c88;">view plain</a><a title="copy" rel="nofollow" href="http://blog.csdn.net/furongkang/article/details/6857610#" style="text-decoration: none; color: #556c88;">copy</a></div><ol start="1" style="margin: 5px 0px 5px 40px; padding: 0px;"><li>//引入头文件&nbsp;&nbsp;</li><li>#include&nbsp;"cn_itcast_ndk3_DataProvider.h"&nbsp;&nbsp;</li><li>#include&nbsp;&lt;string.h&gt;&nbsp;&nbsp;</li><li>//导入日志头文件&nbsp;&nbsp;</li><li>#include&nbsp;&lt;android/log.h&gt;&nbsp;&nbsp;</li><li>//修改日志tag中的值&nbsp;&nbsp;</li><li>#define&nbsp;LOG_TAG&nbsp;"logfromc"&nbsp;&nbsp;</li><li>//日志显示的等级&nbsp;&nbsp;</li><li>#define&nbsp;LOGD(...)&nbsp;__android_log_print(ANDROID_LOG_DEBUG,&nbsp;LOG_TAG,&nbsp;__VA_ARGS__)&nbsp;&nbsp;</li><li>#define&nbsp;LOGI(...)&nbsp;__android_log_print(ANDROID_LOG_INFO,&nbsp;LOG_TAG,&nbsp;__VA_ARGS__)&nbsp;&nbsp;</li><li>&nbsp;&nbsp;</li><li>//&nbsp;java中的jstring,&nbsp;转化为c的一个字符数组&nbsp;&nbsp;</li><li>char*&nbsp;&nbsp;&nbsp;Jstring2CStr(JNIEnv*&nbsp;&nbsp;&nbsp;env,&nbsp;&nbsp;&nbsp;jstring&nbsp;&nbsp;&nbsp;jstr)&nbsp;&nbsp;</li><li>{&nbsp;&nbsp;</li><li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;char*&nbsp;&nbsp;&nbsp;rtn&nbsp;&nbsp;&nbsp;=&nbsp;&nbsp;&nbsp;NULL;&nbsp;&nbsp;</li><li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;jclass&nbsp;&nbsp;&nbsp;clsstring&nbsp;&nbsp;&nbsp;=&nbsp;&nbsp;&nbsp;(*env)-&gt;FindClass(env,"java/lang/String");&nbsp;&nbsp;</li><li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;jstring&nbsp;&nbsp;&nbsp;strencode&nbsp;&nbsp;&nbsp;=&nbsp;&nbsp;&nbsp;(*env)-&gt;NewStringUTF(env,"GB2312");&nbsp;&nbsp;</li><li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;jmethodID&nbsp;&nbsp;&nbsp;mid&nbsp;&nbsp;&nbsp;=&nbsp;&nbsp;&nbsp;(*env)-&gt;GetMethodID(env,clsstring,&nbsp;&nbsp;&nbsp;"getBytes",&nbsp;&nbsp;&nbsp;"(Ljava/lang/String;)[B");&nbsp;&nbsp;</li><li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;jbyteArray&nbsp;&nbsp;&nbsp;barr=&nbsp;&nbsp;&nbsp;(jbyteArray)(*env)-&gt;CallObjectMethod(env,jstr,mid,strencode);&nbsp;//&nbsp;String&nbsp;.getByte("GB2312");&nbsp;&nbsp;</li><li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;jsize&nbsp;&nbsp;&nbsp;alen&nbsp;&nbsp;&nbsp;=&nbsp;&nbsp;&nbsp;(*env)-&gt;GetArrayLength(env,barr);&nbsp;&nbsp;</li><li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;jbyte*&nbsp;&nbsp;&nbsp;ba&nbsp;&nbsp;&nbsp;=&nbsp;&nbsp;&nbsp;(*env)-&gt;GetByteArrayElements(env,barr,JNI_FALSE);&nbsp;&nbsp;</li><li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if(alen&nbsp;&nbsp;&nbsp;&gt;&nbsp;&nbsp;&nbsp;0)&nbsp;&nbsp;</li><li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{&nbsp;&nbsp;</li><li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;rtn&nbsp;&nbsp;&nbsp;=&nbsp;&nbsp;&nbsp;(char*)malloc(alen+1);&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;//new&nbsp;&nbsp;&nbsp;char[alen+1];&nbsp;"\0"&nbsp;&nbsp;</li><li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;memcpy(rtn,ba,alen);&nbsp;&nbsp;</li><li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;rtn[alen]=0;&nbsp;&nbsp;</li><li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;&nbsp;</li><li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(*env)-&gt;ReleaseByteArrayElements(env,barr,ba,0);&nbsp;&nbsp;//释放内存&nbsp;&nbsp;</li><li>&nbsp;&nbsp;</li><li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return&nbsp;rtn;&nbsp;&nbsp;</li><li>}&nbsp;&nbsp;</li><li>&nbsp;&nbsp;</li><li>//处理整形相加&nbsp;&nbsp;</li><li>JNIEXPORT&nbsp;jint&nbsp;JNICALL&nbsp;Java_cn_itcast_ndk3_DataProvider_add&nbsp;&nbsp;</li><li>&nbsp;&nbsp;(JNIEnv&nbsp;*&nbsp;env,&nbsp;jobject&nbsp;obj,&nbsp;jint&nbsp;x,&nbsp;jint&nbsp;y){&nbsp;&nbsp;</li><li>&nbsp;&nbsp;&nbsp;&nbsp;//打印&nbsp;java&nbsp;传递过来的&nbsp;jstring&nbsp;;&nbsp;&nbsp;</li><li>&nbsp;&nbsp;&nbsp;&nbsp;LOGI("log&nbsp;from&nbsp;c&nbsp;code&nbsp;");&nbsp;&nbsp;</li><li>&nbsp;&nbsp;&nbsp;&nbsp;LOGI("x=&nbsp;%ld",x);&nbsp;&nbsp;</li><li>&nbsp;&nbsp;&nbsp;&nbsp;LOGD("y=&nbsp;%ld",y);&nbsp;&nbsp;</li><li>&nbsp;&nbsp;&nbsp;&nbsp;return&nbsp;x+y;&nbsp;&nbsp;</li><li>}&nbsp;&nbsp;</li><li>&nbsp;&nbsp;</li><li>//处理字符串追加&nbsp;&nbsp;</li><li>JNIEXPORT&nbsp;jstring&nbsp;JNICALL&nbsp;Java_cn_itcast_ndk3_DataProvider_sayHelloInC&nbsp;&nbsp;</li><li>&nbsp;&nbsp;(JNIEnv&nbsp;*&nbsp;env,&nbsp;jobject&nbsp;obj,&nbsp;jstring&nbsp;str){&nbsp;&nbsp;</li><li>&nbsp;&nbsp;</li><li>&nbsp;&nbsp;&nbsp;&nbsp;char*&nbsp;p&nbsp;=&nbsp;&nbsp;Jstring2CStr(env,str);&nbsp;&nbsp;</li><li>&nbsp;&nbsp;&nbsp;&nbsp;LOGI("%s",p);&nbsp;&nbsp;</li><li>&nbsp;&nbsp;&nbsp;&nbsp;char*&nbsp;newstr&nbsp;=&nbsp;"append&nbsp;string";&nbsp;&nbsp;</li><li>&nbsp;&nbsp;</li><li>&nbsp;&nbsp;&nbsp;&nbsp;//strcat(dest,&nbsp;sorce)&nbsp;把sorce字符串添加到dest字符串的后面&nbsp;&nbsp;</li><li>&nbsp;&nbsp;&nbsp;&nbsp;LOGI("END");&nbsp;&nbsp;</li><li>&nbsp;&nbsp;&nbsp;&nbsp;return&nbsp;(*env)-&gt;NewStringUTF(env,&nbsp;strcat(p,newstr));&nbsp;&nbsp;</li><li>}&nbsp;&nbsp;</li><li>&nbsp;&nbsp;</li><li>//处理数组中的每一个元素&nbsp;&nbsp;</li><li>JNIEXPORT&nbsp;jintArray&nbsp;JNICALL&nbsp;Java_cn_itcast_ndk3_DataProvider_intMethod&nbsp;&nbsp;</li><li>&nbsp;&nbsp;(JNIEnv&nbsp;*&nbsp;env,&nbsp;jobject&nbsp;obj,&nbsp;jintArray&nbsp;arr){&nbsp;&nbsp;</li><li>&nbsp;&nbsp;&nbsp;&nbsp;//&nbsp;1.获取到&nbsp;arr的大小&nbsp;&nbsp;</li><li>&nbsp;&nbsp;</li><li>&nbsp;&nbsp;&nbsp;&nbsp;int&nbsp;len&nbsp;=&nbsp;(*env)-&gt;GetArrayLength(env,&nbsp;arr);&nbsp;&nbsp;</li><li>&nbsp;&nbsp;&nbsp;&nbsp;LOGI("len=%d",&nbsp;len);&nbsp;&nbsp;</li><li>&nbsp;&nbsp;</li><li>&nbsp;&nbsp;&nbsp;&nbsp;if(len==0){&nbsp;&nbsp;</li><li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return&nbsp;arr;&nbsp;&nbsp;</li><li>&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;&nbsp;</li><li>&nbsp;&nbsp;&nbsp;&nbsp;//取出数组中第一个元素的内存地址&nbsp;&nbsp;</li><li>&nbsp;&nbsp;&nbsp;&nbsp;jint*&nbsp;p&nbsp;=&nbsp;(*env)-&gt;&nbsp;GetIntArrayElements(env,arr,0);&nbsp;&nbsp;</li><li>&nbsp;&nbsp;&nbsp;&nbsp;int&nbsp;i=0;&nbsp;&nbsp;</li><li>&nbsp;&nbsp;&nbsp;&nbsp;for(;i&lt;len;i++){&nbsp;&nbsp;</li><li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;LOGI("len=%ld",&nbsp;*(p+i));//取出的每个元素&nbsp;&nbsp;</li><li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*(p+i)&nbsp;+=&nbsp;5;&nbsp;//取出的每个元素加五&nbsp;&nbsp;</li><li>&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;&nbsp;</li><li>&nbsp;&nbsp;&nbsp;&nbsp;return&nbsp;arr;&nbsp;&nbsp;</li><li>}&nbsp;&nbsp;</li></ol></div><p style="line-height: 28px; margin: 0px 0px 10px; padding: 0px; color: #333333; font-family: 'Hiragino Sans GB W3', 'Hiragino Sans GB', Arial, Helvetica, simsun, u5b8bu4f53; font-size: 16px; background-color: #ffffff;"><strong>编写Android.mk文件</strong></p><div style="line-height: 28px; color: #333333; font-family: 'Hiragino Sans GB W3', 'Hiragino Sans GB', Arial, Helvetica, simsun, u5b8bu4f53; font-size: 16px; background-color: #ffffff;"><div><strong>[cpp]</strong>&nbsp;<a title="view plain" rel="nofollow" href="http://blog.csdn.net/furongkang/article/details/6857610#" style="text-decoration: none; color: #556c88;">view plain</a><a title="copy" rel="nofollow" href="http://blog.csdn.net/furongkang/article/details/6857610#" style="text-decoration: none; color: #556c88;">copy</a></div><ol start="1" style="margin: 5px 0px 5px 40px; padding: 0px;"><li>LOCAL_PATH&nbsp;:=&nbsp;$(call&nbsp;my-dir)&nbsp;&nbsp;</li><li>&nbsp;&nbsp;</li><li>include&nbsp;$(CLEAR_VARS)&nbsp;&nbsp;</li><li>&nbsp;&nbsp;</li><li>LOCAL_MODULE&nbsp;&nbsp;&nbsp;&nbsp;:=&nbsp;Hello&nbsp;&nbsp;</li><li>LOCAL_SRC_FILES&nbsp;:=&nbsp;Hello.c&nbsp;&nbsp;&nbsp;</li><li>#增加&nbsp;log&nbsp;函数对应的log&nbsp;库&nbsp;&nbsp;liblog.so&nbsp;&nbsp;libthread_db.a&nbsp;&nbsp;</li><li>LOCAL_LDLIBS&nbsp;+=&nbsp;-llog&nbsp;&nbsp;</li><li>&nbsp;&nbsp;</li><li>include&nbsp;$(BUILD_SHARED_LIBRARY)&nbsp;&nbsp;</li></ol></div><p style="line-height: 28px; margin: 0px 0px 10px; padding: 0px; color: #333333; font-family: 'Hiragino Sans GB W3', 'Hiragino Sans GB', Arial, Helvetica, simsun, u5b8bu4f53; font-size: 16px; background-color: #ffffff;"><strong>&nbsp;Java代码load 动态库.调用native代码</strong></p><div style="line-height: 28px; color: #333333; font-family: 'Hiragino Sans GB W3', 'Hiragino Sans GB', Arial, Helvetica, simsun, u5b8bu4f53; font-size: 16px; background-color: #ffffff;"><div><strong>[java]</strong>&nbsp;<a title="view plain" rel="nofollow" href="http://blog.csdn.net/furongkang/article/details/6857610#" style="text-decoration: none; color: #556c88;">view plain</a><a title="copy" rel="nofollow" href="http://blog.csdn.net/furongkang/article/details/6857610#" style="text-decoration: none; color: #556c88;">copy</a></div><ol start="1" style="margin: 5px 0px 5px 40px; padding: 0px;"><li>static{&nbsp;&nbsp;</li><li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;System.loadLibrary("Hello");&nbsp;&nbsp;</li><li>&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;&nbsp;</li><li>&nbsp;&nbsp;&nbsp;&nbsp;DataProvider&nbsp;dp;&nbsp;&nbsp;</li><li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</li><li>&nbsp;&nbsp;&nbsp;&nbsp;@Override&nbsp;&nbsp;</li><li>&nbsp;&nbsp;&nbsp;&nbsp;public&nbsp;void&nbsp;onCreate(Bundle&nbsp;savedInstanceState)&nbsp;{&nbsp;&nbsp;</li><li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;super.onCreate(savedInstanceState);&nbsp;&nbsp;</li><li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;setContentView(R.layout.main);&nbsp;&nbsp;</li><li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;dp&nbsp;=&nbsp;new&nbsp;DataProvider();&nbsp;&nbsp;</li><li>&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;&nbsp;</li><li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</li><li>&nbsp;&nbsp;&nbsp;&nbsp;//add对应的事件&nbsp;&nbsp;</li><li>&nbsp;&nbsp;&nbsp;&nbsp;public&nbsp;void&nbsp;add(View&nbsp;view){&nbsp;&nbsp;</li><li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;//执行C语言处理数据&nbsp;&nbsp;</li><li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;int&nbsp;result&nbsp;=&nbsp;dp.add(3,&nbsp;5);&nbsp;&nbsp;</li><li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Toast.makeText(this,&nbsp;"相加的结果"+&nbsp;result,&nbsp;1).show();&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</li><li>&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;&nbsp;</li></ol></div><p style="line-height: 28px; margin: 0px 0px 10px; padding: 0px; color: #333333; font-family: 'Hiragino Sans GB W3', 'Hiragino Sans GB', Arial, Helvetica, simsun, u5b8bu4f53; font-size: 16px; background-color: #ffffff;">&nbsp;</p><p style="line-height: 28px; margin: 0px 0px 10px; padding: 0px; color: #333333; font-family: 'Hiragino Sans GB W3', 'Hiragino Sans GB', Arial, Helvetica, simsun, u5b8bu4f53; font-size: 16px; background-color: #ffffff;"><span style="line-height: 31px; font-size: 18px;"><strong>C中回调java方法</strong></span></p><p style="line-height: 28px; margin: 0px 0px 10px; padding: 0px; color: #333333; font-family: 'Hiragino Sans GB W3', 'Hiragino Sans GB', Arial, Helvetica, simsun, u5b8bu4f53; font-size: 16px; background-color: #ffffff;"><strong>声明native 方法：</strong></p><div style="line-height: 28px; color: #333333; font-family: 'Hiragino Sans GB W3', 'Hiragino Sans GB', Arial, Helvetica, simsun, u5b8bu4f53; font-size: 16px; background-color: #ffffff;"><div><strong>[java]</strong>&nbsp;<a title="view plain" rel="nofollow" href="http://blog.csdn.net/furongkang/article/details/6857610#" style="text-decoration: none; color: #556c88;">view plain</a><a title="copy" rel="nofollow" href="http://blog.csdn.net/furongkang/article/details/6857610#" style="text-decoration: none; color: #556c88;">copy</a></div><ol start="1" style="margin: 5px 0px 5px 40px; padding: 0px;"><li>public&nbsp;class&nbsp;DataProvider{&nbsp;&nbsp;</li><li>&nbsp;&nbsp;&nbsp;&nbsp;public&nbsp;native&nbsp;void&nbsp;callCcode();&nbsp;&nbsp;</li><li>&nbsp;&nbsp;&nbsp;&nbsp;public&nbsp;native&nbsp;void&nbsp;callCcode1();&nbsp;&nbsp;</li><li>&nbsp;&nbsp;&nbsp;&nbsp;public&nbsp;native&nbsp;void&nbsp;callCcode2();&nbsp;&nbsp;</li><li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</li><li>&nbsp;&nbsp;&nbsp;&nbsp;///C调用java中的空方法&nbsp;&nbsp;&nbsp;&nbsp;</li><li>&nbsp;&nbsp;&nbsp;&nbsp;public&nbsp;void&nbsp;helloFromJava(){&nbsp;&nbsp;</li><li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;System.out.println("hello&nbsp;from&nbsp;java&nbsp;");&nbsp;&nbsp;</li><li>&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;&nbsp;</li><li>&nbsp;&nbsp;&nbsp;&nbsp;//C调用java中的带两个int参数的方法&nbsp;&nbsp;</li><li>&nbsp;&nbsp;&nbsp;&nbsp;public&nbsp;int&nbsp;Add(int&nbsp;x,int&nbsp;y){&nbsp;&nbsp;</li><li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;System.out.println("相加的结果为"+&nbsp;(x+y));&nbsp;&nbsp;</li><li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return&nbsp;x+y;&nbsp;&nbsp;</li><li>&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;&nbsp;</li><li>&nbsp;&nbsp;&nbsp;&nbsp;//C调用java中参数为string的方法&nbsp;&nbsp;</li><li>&nbsp;&nbsp;&nbsp;&nbsp;public&nbsp;void&nbsp;printString(String&nbsp;s){&nbsp;&nbsp;</li><li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;System.out.println("in&nbsp;java&nbsp;code&nbsp;"+&nbsp;s);&nbsp;&nbsp;</li><li>&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;&nbsp;</li><li>}&nbsp;&nbsp;</li></ol></div><p style="line-height: 28px; margin: 0px 0px 10px; padding: 0px; color: #333333; font-family: 'Hiragino Sans GB W3', 'Hiragino Sans GB', Arial, Helvetica, simsun, u5b8bu4f53; font-size: 16px; background-color: #ffffff;"><strong>头文件可以用jdk自带的javah进行自动生成，使用javap -s可以获取到方法的签名。</strong></p><p style="line-height: 28px; margin: 0px 0px 10px; padding: 0px; color: #333333; font-family: 'Hiragino Sans GB W3', 'Hiragino Sans GB', Arial, Helvetica, simsun, u5b8bu4f53; font-size: 16px; background-color: #ffffff;"><strong>C代码实现回调需要三个步骤：首先要要获取到 某个对象 , 然后获取对象里面的方法&nbsp; ,最后 调用这个方法&nbsp; .</strong></p><div style="line-height: 28px; color: #333333; font-family: 'Hiragino Sans GB W3', 'Hiragino Sans GB', Arial, Helvetica, simsun, u5b8bu4f53; font-size: 16px; background-color: #ffffff;"><div><strong>[cpp]</strong>&nbsp;<a title="view plain" rel="nofollow" href="http://blog.csdn.net/furongkang/article/details/6857610#" style="text-decoration: none; color: #556c88;">view plain</a><a title="copy" rel="nofollow" href="http://blog.csdn.net/furongkang/article/details/6857610#" style="text-decoration: none; color: #556c88;">copy</a></div><ol start="1" style="margin: 5px 0px 5px 40px; padding: 0px;"><li>#include&nbsp;"cn_itcast_ndk4_DataProvider.h"&nbsp;&nbsp;</li><li>#include&nbsp;&lt;string.h&gt;&nbsp;&nbsp;</li><li>#include&nbsp;&lt;android/log.h&gt;&nbsp;&nbsp;</li><li>#define&nbsp;LOG_TAG&nbsp;"logfromc"&nbsp;&nbsp;</li><li>#define&nbsp;LOGD(...)&nbsp;__android_log_print(ANDROID_LOG_DEBUG,&nbsp;LOG_TAG,&nbsp;__VA_ARGS__)&nbsp;&nbsp;</li><li>#define&nbsp;LOGI(...)&nbsp;__android_log_print(ANDROID_LOG_INFO,&nbsp;LOG_TAG,&nbsp;__VA_ARGS__)&nbsp;&nbsp;</li><li>&nbsp;&nbsp;</li><li>//1.调用java中的无参helloFromJava方法&nbsp;&nbsp;</li><li>JNIEXPORT&nbsp;void&nbsp;JNICALL&nbsp;Java_cn_itcast_ndk4_DataProvider_callCcode&nbsp;&nbsp;</li><li>&nbsp;&nbsp;(JNIEnv&nbsp;*&nbsp;env&nbsp;,&nbsp;jobject&nbsp;obj){&nbsp;&nbsp;</li><li>&nbsp;&nbsp;&nbsp;&nbsp;//&nbsp;获取到DataProvider对象&nbsp;&nbsp;</li><li>&nbsp;&nbsp;&nbsp;&nbsp;char*&nbsp;classname&nbsp;=&nbsp;"cn/itcast/ndk4/DataProvider";&nbsp;&nbsp;</li><li>&nbsp;&nbsp;&nbsp;&nbsp;jclass&nbsp;dpclazz&nbsp;=&nbsp;(*env)-&gt;FindClass(env,classname);&nbsp;&nbsp;</li><li>&nbsp;&nbsp;&nbsp;&nbsp;if&nbsp;(dpclazz&nbsp;==&nbsp;0)&nbsp;{&nbsp;&nbsp;</li><li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;LOGI("not&nbsp;find&nbsp;class!");&nbsp;&nbsp;</li><li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;else&nbsp;&nbsp;</li><li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;LOGI("find&nbsp;class");&nbsp;&nbsp;</li><li>&nbsp;&nbsp;&nbsp;&nbsp;//第三个参数&nbsp;和第四个参数&nbsp;是方法的签名,第三个参数是方法名&nbsp;&nbsp;,&nbsp;第四个参数是根据返回值和参数生成的&nbsp;&nbsp;</li><li>&nbsp;&nbsp;&nbsp;&nbsp;//获取到DataProvider要调用的方法&nbsp;&nbsp;</li><li>&nbsp;&nbsp;&nbsp;&nbsp;jmethodID&nbsp;methodID&nbsp;=&nbsp;(*env)-&gt;GetMethodID(env,dpclazz,"helloFromJava","()V");&nbsp;&nbsp;</li><li>&nbsp;&nbsp;&nbsp;&nbsp;if&nbsp;(methodID&nbsp;==&nbsp;0)&nbsp;{&nbsp;&nbsp;</li><li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;LOGI("not&nbsp;find&nbsp;method!");&nbsp;&nbsp;</li><li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;else&nbsp;&nbsp;</li><li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;LOGI("find&nbsp;method");&nbsp;&nbsp;</li><li>&nbsp;&nbsp;&nbsp;&nbsp;//调用这个方法&nbsp;&nbsp;</li><li>&nbsp;&nbsp;&nbsp;&nbsp;(*env)-&gt;CallVoidMethod(env,&nbsp;obj,methodID);&nbsp;&nbsp;</li><li>}&nbsp;&nbsp;</li><li>&nbsp;&nbsp;</li><li>//&nbsp;2.调用java中的printString方法传递一个字符串&nbsp;&nbsp;</li><li>JNIEXPORT&nbsp;void&nbsp;JNICALL&nbsp;Java_cn_itcast_ndk4_DataProvider_callCcode1&nbsp;&nbsp;</li><li>&nbsp;&nbsp;(JNIEnv&nbsp;*&nbsp;env,&nbsp;jobject&nbsp;obj){&nbsp;&nbsp;</li><li>&nbsp;&nbsp;&nbsp;&nbsp;LOGI("in&nbsp;code");&nbsp;&nbsp;</li><li>&nbsp;&nbsp;&nbsp;&nbsp;//&nbsp;获取到DataProvider对象&nbsp;&nbsp;</li><li>&nbsp;&nbsp;&nbsp;&nbsp;char*&nbsp;classname&nbsp;=&nbsp;"cn/itcast/ndk4/DataProvider";&nbsp;&nbsp;</li><li>&nbsp;&nbsp;&nbsp;&nbsp;jclass&nbsp;dpclazz&nbsp;=&nbsp;(*env)-&gt;FindClass(env,classname);&nbsp;&nbsp;</li><li>&nbsp;&nbsp;&nbsp;&nbsp;if&nbsp;(dpclazz&nbsp;==&nbsp;0)&nbsp;{&nbsp;&nbsp;</li><li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;LOGI("not&nbsp;find&nbsp;class!");&nbsp;&nbsp;</li><li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;else&nbsp;&nbsp;</li><li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;LOGI("find&nbsp;class");&nbsp;&nbsp;</li><li>&nbsp;&nbsp;&nbsp;&nbsp;//&nbsp;获取到要调用的method&nbsp;&nbsp;</li><li>&nbsp;&nbsp;&nbsp;&nbsp;jmethodID&nbsp;methodID&nbsp;=&nbsp;(*env)-&gt;GetMethodID(env,dpclazz,"printString","(Ljava/lang/String;)V");&nbsp;&nbsp;</li><li>&nbsp;&nbsp;&nbsp;&nbsp;if&nbsp;(methodID&nbsp;==&nbsp;0)&nbsp;{&nbsp;&nbsp;</li><li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;LOGI("not&nbsp;find&nbsp;method!");&nbsp;&nbsp;</li><li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;else&nbsp;&nbsp;</li><li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;LOGI("find&nbsp;method");&nbsp;&nbsp;</li><li>&nbsp;&nbsp;</li><li>&nbsp;&nbsp;&nbsp;&nbsp;//调用这个方法&nbsp;&nbsp;</li><li>&nbsp;&nbsp;&nbsp;&nbsp;(*env)-&gt;CallVoidMethod(env,&nbsp;obj,methodID,(*env)-&gt;NewStringUTF(env,"haha"));&nbsp;&nbsp;</li><li>}&nbsp;&nbsp;</li><li>&nbsp;&nbsp;</li><li>//&nbsp;3.&nbsp;调用java中的add方法&nbsp;,&nbsp;传递两个参数&nbsp;jint&nbsp;x,y&nbsp;&nbsp;</li><li>JNIEXPORT&nbsp;void&nbsp;JNICALL&nbsp;Java_cn_itcast_ndk4_DataProvider_callCcode2&nbsp;&nbsp;</li><li>&nbsp;&nbsp;(JNIEnv&nbsp;*&nbsp;env,&nbsp;jobject&nbsp;obj){&nbsp;&nbsp;</li><li>&nbsp;&nbsp;&nbsp;&nbsp;char*&nbsp;classname&nbsp;=&nbsp;"cn/itcast/ndk4/DataProvider";&nbsp;&nbsp;</li><li>&nbsp;&nbsp;&nbsp;&nbsp;jclass&nbsp;dpclazz&nbsp;=&nbsp;(*env)-&gt;FindClass(env,classname);&nbsp;&nbsp;</li><li>&nbsp;&nbsp;&nbsp;&nbsp;jmethodID&nbsp;methodID&nbsp;=&nbsp;(*env)-&gt;GetMethodID(env,dpclazz,"Add","(II)I");&nbsp;&nbsp;</li><li>&nbsp;&nbsp;&nbsp;&nbsp;(*env)-&gt;CallIntMethod(env,&nbsp;obj,methodID,3l,4l);&nbsp;&nbsp;</li><li>} &nbsp;</li></ol></div><img src ="http://www.cppblog.com/xkjy3000/aggbug/204416.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/xkjy3000/" target="_blank">虚空骄阳</a> 2013-11-24 13:04 <a href="http://www.cppblog.com/xkjy3000/archive/2013/11/24/204416.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Android jni中数组参数的传递方式</title><link>http://www.cppblog.com/xkjy3000/archive/2013/11/24/204415.html</link><dc:creator>虚空骄阳</dc:creator><author>虚空骄阳</author><pubDate>Sun, 24 Nov 2013 05:03:00 GMT</pubDate><guid>http://www.cppblog.com/xkjy3000/archive/2013/11/24/204415.html</guid><wfw:comment>http://www.cppblog.com/xkjy3000/comments/204415.html</wfw:comment><comments>http://www.cppblog.com/xkjy3000/archive/2013/11/24/204415.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/xkjy3000/comments/commentRss/204415.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/xkjy3000/services/trackbacks/204415.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp;&nbsp; 摘要: 1、背景今天调试了一下Android jni关于Java中调用C代码的程序，发现我的数组参数传递方式不对，导致值传递不正确，我的方法是：C代码，入口函数&nbsp;#include &lt;stdio.h&gt;#include &lt;jni.h&gt;jint Java_sony_MedicalRecordDemo_MainActivity_decryptionSuccess(JNIEnv* ...&nbsp;&nbsp;<a href='http://www.cppblog.com/xkjy3000/archive/2013/11/24/204415.html'>阅读全文</a><img src ="http://www.cppblog.com/xkjy3000/aggbug/204415.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/xkjy3000/" target="_blank">虚空骄阳</a> 2013-11-24 13:03 <a href="http://www.cppblog.com/xkjy3000/archive/2013/11/24/204415.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Android NDK 开发教程七：调试</title><link>http://www.cppblog.com/xkjy3000/archive/2013/11/24/204414.html</link><dc:creator>虚空骄阳</dc:creator><author>虚空骄阳</author><pubDate>Sun, 24 Nov 2013 05:02:00 GMT</pubDate><guid>http://www.cppblog.com/xkjy3000/archive/2013/11/24/204414.html</guid><wfw:comment>http://www.cppblog.com/xkjy3000/comments/204414.html</wfw:comment><comments>http://www.cppblog.com/xkjy3000/archive/2013/11/24/204414.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/xkjy3000/comments/commentRss/204414.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/xkjy3000/services/trackbacks/204414.html</trackback:ping><description><![CDATA[<p style="line-height: 28px; margin: 0px 0px 10px; padding: 0px; color: #333333; font-family: 'Hiragino Sans GB W3', 'Hiragino Sans GB', Arial, Helvetica, simsun, u5b8bu4f53; font-size: 16px; background-color: #ffffff;">开发应用一个关键的步骤是调试，对于NDK的C代码调试有很多种方法，</p><ul style="line-height: 28px; margin: 5px 0px 5px 40px; padding: 0px; color: #333333; font-family: 'Hiragino Sans GB W3', 'Hiragino Sans GB', Arial, Helvetica, simsun, u5b8bu4f53; font-size: 16px; background-color: #ffffff;"><li>对于和Android平台相关性不大的部分代码，可以单独创建一个C/C++项目，编写测试代码，测试完成后，再编译成NDK动态库或静态库模块。</li><li>使用NDK-GDB，NDK-GDB的命令行调试方法和GDB类似，网络有很多关于GDB的<a rel="nofollow" href="http://www.cs.cmu.edu/~gilpin/tutorial/" style="text-decoration: none; color: #556c88;">教程</a></li><li>使用<a rel="nofollow" href="http://www.cnblogs.com/shadox/archive/2011/12/02/2272564.html" style="text-decoration: none; color: #556c88;">Eclipse+CDT+GDB调试android NDK程序</a>&nbsp;实时调试，不过这种方法设置起来不是十分方便，调试起来需要在GDB和Eclipse之间来回切换，适合于有经验的程序员。</li><li>这里介绍一个开发嵌入式系统调试的&#8220;终极工具:-)&#8221;-printf. 开发嵌入式系统调试常用的也是最简单的方法，是使用printf 打印调试信息。</li></ul><p style="line-height: 28px; margin: 0px 0px 10px; padding: 0px; color: #333333; font-family: 'Hiragino Sans GB W3', 'Hiragino Sans GB', Arial, Helvetica, simsun, u5b8bu4f53; font-size: 16px; background-color: #ffffff;">修改一下<a rel="nofollow" href="http://www.imobilebbs.com/wordpress/?p=2924" style="text-decoration: none; color: #556c88;">two-lib 的例子&nbsp;</a>，使用first.c 中的first 函数实现一个加法计算器<br /><img src="http://www.cppblog.com/images/cppblog_com/xkjy3000/FFF.png" width="480" height="800" align="absMiddle" alt="" /><br /></p><p style="line-height: 28px; margin: 0px 0px 10px; padding: 0px; color: #333333; font-family: 'Hiragino Sans GB W3', 'Hiragino Sans GB', Arial, Helvetica, simsun, u5b8bu4f53; font-size: 16px; background-color: #ffffff;">这里我们想在调用first(int x,int y) 显示出传入的x ,y 值。Android NDK 中提供了一个Log库，其头文件为android/log.h ，可以提供Androd Java代码中的Log功能，也是可以在LogCat中打印信息。</p><p style="line-height: 28px; margin: 0px 0px 10px; padding: 0px; color: #333333; font-family: 'Hiragino Sans GB W3', 'Hiragino Sans GB', Arial, Helvetica, simsun, u5b8bu4f53; font-size: 16px; background-color: #ffffff;">具体方法如下：</p><p style="line-height: 28px; margin: 0px 0px 10px; padding: 0px; color: #333333; font-family: 'Hiragino Sans GB W3', 'Hiragino Sans GB', Arial, Helvetica, simsun, u5b8bu4f53; font-size: 16px; background-color: #ffffff;">1. 修改first.c ,添加合适的打印语句</p><span style="color: #333333; font-family: 'Hiragino Sans GB W3', 'Hiragino Sans GB', Arial, Helvetica, simsun, u5b8bu4f53; font-size: 16px; line-height: 28px; background-color: #ffffff;">#include "first.h"</span><br style="line-height: 28px; color: #333333; font-family: 'Hiragino Sans GB W3', 'Hiragino Sans GB', Arial, Helvetica, simsun, u5b8bu4f53; font-size: 16px; background-color: #ffffff;" /><span style="color: #333333; font-family: 'Hiragino Sans GB W3', 'Hiragino Sans GB', Arial, Helvetica, simsun, u5b8bu4f53; font-size: 16px; line-height: 28px; background-color: #ffffff;">#include &lt;android/log.h&gt;</span><br style="line-height: 28px; color: #333333; font-family: 'Hiragino Sans GB W3', 'Hiragino Sans GB', Arial, Helvetica, simsun, u5b8bu4f53; font-size: 16px; background-color: #ffffff;" /><br style="line-height: 28px; color: #333333; font-family: 'Hiragino Sans GB W3', 'Hiragino Sans GB', Arial, Helvetica, simsun, u5b8bu4f53; font-size: 16px; background-color: #ffffff;" /><span style="color: #333333; font-family: 'Hiragino Sans GB W3', 'Hiragino Sans GB', Arial, Helvetica, simsun, u5b8bu4f53; font-size: 16px; line-height: 28px; background-color: #ffffff;">int&nbsp; first(int&nbsp; x, int&nbsp; y)</span><br style="line-height: 28px; color: #333333; font-family: 'Hiragino Sans GB W3', 'Hiragino Sans GB', Arial, Helvetica, simsun, u5b8bu4f53; font-size: 16px; background-color: #ffffff;" /><span style="color: #333333; font-family: 'Hiragino Sans GB W3', 'Hiragino Sans GB', Arial, Helvetica, simsun, u5b8bu4f53; font-size: 16px; line-height: 28px; background-color: #ffffff;">{</span><br style="line-height: 28px; color: #333333; font-family: 'Hiragino Sans GB W3', 'Hiragino Sans GB', Arial, Helvetica, simsun, u5b8bu4f53; font-size: 16px; background-color: #ffffff;" /><span style="color: #333333; font-family: 'Hiragino Sans GB W3', 'Hiragino Sans GB', Arial, Helvetica, simsun, u5b8bu4f53; font-size: 16px; line-height: 28px; background-color: #ffffff;">&nbsp;__android_log_print(ANDROID_LOG_INFO, "MYPROG", "x = %d, y =%d", x,y);</span><br style="line-height: 28px; color: #333333; font-family: 'Hiragino Sans GB W3', 'Hiragino Sans GB', Arial, Helvetica, simsun, u5b8bu4f53; font-size: 16px; background-color: #ffffff;" /><span style="color: #333333; font-family: 'Hiragino Sans GB W3', 'Hiragino Sans GB', Arial, Helvetica, simsun, u5b8bu4f53; font-size: 16px; line-height: 28px; background-color: #ffffff;">&nbsp;return x + y;</span><br style="line-height: 28px; color: #333333; font-family: 'Hiragino Sans GB W3', 'Hiragino Sans GB', Arial, Helvetica, simsun, u5b8bu4f53; font-size: 16px; background-color: #ffffff;" /><span style="color: #333333; font-family: 'Hiragino Sans GB W3', 'Hiragino Sans GB', Arial, Helvetica, simsun, u5b8bu4f53; font-size: 16px; line-height: 28px; background-color: #ffffff;">}</span><br style="line-height: 28px; color: #333333; font-family: 'Hiragino Sans GB W3', 'Hiragino Sans GB', Arial, Helvetica, simsun, u5b8bu4f53; font-size: 16px; background-color: #ffffff;" /><br style="line-height: 28px; color: #333333; font-family: 'Hiragino Sans GB W3', 'Hiragino Sans GB', Arial, Helvetica, simsun, u5b8bu4f53; font-size: 16px; background-color: #ffffff;" /><span style="color: #333333; font-family: 'Hiragino Sans GB W3', 'Hiragino Sans GB', Arial, Helvetica, simsun, u5b8bu4f53; font-size: 16px; line-height: 28px; background-color: #ffffff;">2. 修改android.mk 文件，添加需要链接的Log库</span><p style="line-height: 28px; margin: 0px 0px 10px; padding: 0px; color: #333333; font-family: 'Hiragino Sans GB W3', 'Hiragino Sans GB', Arial, Helvetica, simsun, u5b8bu4f53; font-size: 16px; background-color: #ffffff;">LOCAL_PATH:= $(call my-dir)</p><p style="line-height: 28px; margin: 0px 0px 10px; padding: 0px; color: #333333; font-family: 'Hiragino Sans GB W3', 'Hiragino Sans GB', Arial, Helvetica, simsun, u5b8bu4f53; font-size: 16px; background-color: #ffffff;"># first lib, which will be built statically<br />#<br />include $(CLEAR_VARS)</p><p style="line-height: 28px; margin: 0px 0px 10px; padding: 0px; color: #333333; font-family: 'Hiragino Sans GB W3', 'Hiragino Sans GB', Arial, Helvetica, simsun, u5b8bu4f53; font-size: 16px; background-color: #ffffff;">LOCAL_MODULE&nbsp;&nbsp;&nbsp; := libtwolib-first<br />LOCAL_SRC_FILES := first.c</p><p style="line-height: 28px; margin: 0px 0px 10px; padding: 0px; color: #333333; font-family: 'Hiragino Sans GB W3', 'Hiragino Sans GB', Arial, Helvetica, simsun, u5b8bu4f53; font-size: 16px; background-color: #ffffff;">include $(BUILD_STATIC_LIBRARY)</p><p style="line-height: 28px; margin: 0px 0px 10px; padding: 0px; color: #333333; font-family: 'Hiragino Sans GB W3', 'Hiragino Sans GB', Arial, Helvetica, simsun, u5b8bu4f53; font-size: 16px; background-color: #ffffff;"># second lib, which will depend on and include the first one<br />#<br />include $(CLEAR_VARS)</p><p style="line-height: 28px; margin: 0px 0px 10px; padding: 0px; color: #333333; font-family: 'Hiragino Sans GB W3', 'Hiragino Sans GB', Arial, Helvetica, simsun, u5b8bu4f53; font-size: 16px; background-color: #ffffff;">LOCAL_MODULE&nbsp;&nbsp;&nbsp; := libtwolib-second<br />LOCAL_SRC_FILES := second.c<br /><strong><span style="color: #3366ff;">LOCAL_LDLIBS := -llog</span></strong><br />LOCAL_STATIC_LIBRARIES := libtwolib-first</p><p style="line-height: 28px; margin: 0px 0px 10px; padding: 0px; color: #333333; font-family: 'Hiragino Sans GB W3', 'Hiragino Sans GB', Arial, Helvetica, simsun, u5b8bu4f53; font-size: 16px; background-color: #ffffff;">include $(BUILD_SHARED_LIBRARY)</p><p style="line-height: 28px; margin: 0px 0px 10px; padding: 0px; color: #333333; font-family: 'Hiragino Sans GB W3', 'Hiragino Sans GB', Arial, Helvetica, simsun, u5b8bu4f53; font-size: 16px; background-color: #ffffff;">然后就可以编译Native C代码，运行这个例子，可以在LogCat看到打印的信息：<br /><img src="http://www.cppblog.com/images/cppblog_com/xkjy3000/GGG.png" width="818" height="133" align="absMiddle" alt="" /><br />本例<a rel="nofollow" href="http://www.imobilebbs.com/download/android/two-libs.zip" style="text-decoration: none; color: #556c88;">下载</a><br /></p><img src ="http://www.cppblog.com/xkjy3000/aggbug/204414.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/xkjy3000/" target="_blank">虚空骄阳</a> 2013-11-24 13:02 <a href="http://www.cppblog.com/xkjy3000/archive/2013/11/24/204414.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Android NDK 开发教程六： application.mk</title><link>http://www.cppblog.com/xkjy3000/archive/2013/11/24/204413.html</link><dc:creator>虚空骄阳</dc:creator><author>虚空骄阳</author><pubDate>Sun, 24 Nov 2013 04:59:00 GMT</pubDate><guid>http://www.cppblog.com/xkjy3000/archive/2013/11/24/204413.html</guid><wfw:comment>http://www.cppblog.com/xkjy3000/comments/204413.html</wfw:comment><comments>http://www.cppblog.com/xkjy3000/archive/2013/11/24/204413.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/xkjy3000/comments/commentRss/204413.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/xkjy3000/services/trackbacks/204413.html</trackback:ping><description><![CDATA[<p style="line-height: 28px; margin: 0px 0px 10px; padding: 0px; color: #333333; font-family: 'Hiragino Sans GB W3', 'Hiragino Sans GB', Arial, Helvetica, simsun, u5b8bu4f53; font-size: 16px; background-color: #ffffff;">配合android.mk 使用的make 文件还有一个application.mk ，大部分情况无需修改该文件，下面也来自<a rel="nofollow" href="http://www.iteye.com/topic/1113483" style="text-decoration: none; color: #556c88;">网络翻译</a></p><p style="line-height: 28px; margin: 0px 0px 10px; padding: 0px; color: #333333; font-family: 'Hiragino Sans GB W3', 'Hiragino Sans GB', Arial, Helvetica, simsun, u5b8bu4f53; font-size: 16px; background-color: #ffffff;">Application.mk文件</p><p style="line-height: 28px; margin: 0px 0px 10px; padding: 0px; color: #333333; font-family: 'Hiragino Sans GB W3', 'Hiragino Sans GB', Arial, Helvetica, simsun, u5b8bu4f53; font-size: 16px; background-color: #ffffff;">简介：<br />&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8211;<br />要将C\C++代码编译为SO文件，光有Android.mk文件还不行，还需要一个Application.mk文件。<br />本文档是描述你的Android应用程序中需要的本地模块的Application.mk的语法使用，要明白如下。</p><p style="line-height: 28px; margin: 0px 0px 10px; padding: 0px; color: #333333; font-family: 'Hiragino Sans GB W3', 'Hiragino Sans GB', Arial, Helvetica, simsun, u5b8bu4f53; font-size: 16px; background-color: #ffffff;">Application.mk目的是描述在你的应用程序中所需要的模块(即静态库或动态库)。</p><p style="line-height: 28px; margin: 0px 0px 10px; padding: 0px; color: #333333; font-family: 'Hiragino Sans GB W3', 'Hiragino Sans GB', Arial, Helvetica, simsun, u5b8bu4f53; font-size: 16px; background-color: #ffffff;">Application.mk文件通常被放置在$PROJECT/jni/Application.mk下，$PROJECT指的是您的项目。</p><p style="line-height: 28px; margin: 0px 0px 10px; padding: 0px; color: #333333; font-family: 'Hiragino Sans GB W3', 'Hiragino Sans GB', Arial, Helvetica, simsun, u5b8bu4f53; font-size: 16px; background-color: #ffffff;">另一种方法是将其放在顶层的子目录下：<br />$NDK/apps目录下，例如：<br />$NDK/apps/&lt;myapp&gt;/Application.mk</p><p style="line-height: 28px; margin: 0px 0px 10px; padding: 0px; color: #333333; font-family: 'Hiragino Sans GB W3', 'Hiragino Sans GB', Arial, Helvetica, simsun, u5b8bu4f53; font-size: 16px; background-color: #ffffff;">&lt;myapp&gt;是一个简称，用于描述你的NDK编译系统的应用程序（这个名字不会生成共享库或者最终的包）</p><p style="line-height: 28px; margin: 0px 0px 10px; padding: 0px; color: #333333; font-family: 'Hiragino Sans GB W3', 'Hiragino Sans GB', Arial, Helvetica, simsun, u5b8bu4f53; font-size: 16px; background-color: #ffffff;">下面是Application.mk中定义的几个变量。</p><p style="line-height: 28px; margin: 0px 0px 10px; padding: 0px; color: #333333; font-family: 'Hiragino Sans GB W3', 'Hiragino Sans GB', Arial, Helvetica, simsun, u5b8bu4f53; font-size: 16px; background-color: #ffffff;">APP_PROJECT_PATH<br />这个变量是强制性的，并且会给出应用程序工程的根目录的一个绝对路径。这是用来复制或者安装一个没有任何版本限制的JNI库，从而给APK生成工具一个详细的路径。</p><p style="line-height: 28px; margin: 0px 0px 10px; padding: 0px; color: #333333; font-family: 'Hiragino Sans GB W3', 'Hiragino Sans GB', Arial, Helvetica, simsun, u5b8bu4f53; font-size: 16px; background-color: #ffffff;">APP_MODULES<br />这个变量是可选的，如果没有定义，NDK将由在Android.mk中声明的默认的模块编译，并且包含所有的子文件（makefile文件）<br />如果APP_MODULES定义了，它不许是一个空格分隔的模块列表，这个模块名字被定义在Android.mk文件中的LOCAL_MODULE中。注意NDK会自动计算模块的依赖</p><p style="line-height: 28px; margin: 0px 0px 10px; padding: 0px; color: #333333; font-family: 'Hiragino Sans GB W3', 'Hiragino Sans GB', Arial, Helvetica, simsun, u5b8bu4f53; font-size: 16px; background-color: #ffffff;">注意：NDK在R4开始改变了这个变量的行为，再次之前：<br />- 在您的Application.mk中，该变量是强制的<br />- 必须明确列出所有需要的模块</p><p style="line-height: 28px; margin: 0px 0px 10px; padding: 0px; color: #333333; font-family: 'Hiragino Sans GB W3', 'Hiragino Sans GB', Arial, Helvetica, simsun, u5b8bu4f53; font-size: 16px; background-color: #ffffff;">APP_OPTIM<br />这个变量是可选的，用来定义&#8220;release&#8221;或&#8221;debug&#8221;。在编译您的应用程序模块的时候，可以用来改变优先级。</p><p style="line-height: 28px; margin: 0px 0px 10px; padding: 0px; color: #333333; font-family: 'Hiragino Sans GB W3', 'Hiragino Sans GB', Arial, Helvetica, simsun, u5b8bu4f53; font-size: 16px; background-color: #ffffff;">&#8220;release&#8221;模式是默认的，并且会生成高度优化的二进制代码。&#8221;debug&#8221;模式生成的是未优化的二进制代码，但可以检测出很多的BUG，可以用于调试。</p><p style="line-height: 28px; margin: 0px 0px 10px; padding: 0px; color: #333333; font-family: 'Hiragino Sans GB W3', 'Hiragino Sans GB', Arial, Helvetica, simsun, u5b8bu4f53; font-size: 16px; background-color: #ffffff;">注意：如果你的应用程序是可调试的（即，如果你的清单文件中设置了android:debuggable的属性是&#8221;true&#8221;）。默认的是&#8221;debug&#8221;而不是&#8221;release&#8221;。这可以通过设置APP_OPTIM为&#8221;release&#8221;来将其覆盖。</p><p style="line-height: 28px; margin: 0px 0px 10px; padding: 0px; color: #333333; font-family: 'Hiragino Sans GB W3', 'Hiragino Sans GB', Arial, Helvetica, simsun, u5b8bu4f53; font-size: 16px; background-color: #ffffff;">注意：可以在&#8221;release&#8221;和&#8221;debug&#8221;模式下一起调试，但是&#8221;release&#8221;模式编译后将会提供更少的BUG信息。在我们清楚BUG的 过程中，有一些变量被优化了，或者根本就无法被检测出来，代码的重新排序会让这些带阿弥变得更加难以阅读，并且让这些轨迹更加不可靠。</p><p style="line-height: 28px; margin: 0px 0px 10px; padding: 0px; color: #333333; font-family: 'Hiragino Sans GB W3', 'Hiragino Sans GB', Arial, Helvetica, simsun, u5b8bu4f53; font-size: 16px; background-color: #ffffff;">APP_CFLAGS<br />当编译模块中有任何C文件或者C++文件的时候，C编译器的信号就会被发出。这里可以在你的应用中需要这些模块时，进行编译的调整，这样就不许要直接更改Android.mk为文件本身了</p><p style="line-height: 28px; margin: 0px 0px 10px; padding: 0px; color: #333333; font-family: 'Hiragino Sans GB W3', 'Hiragino Sans GB', Arial, Helvetica, simsun, u5b8bu4f53; font-size: 16px; background-color: #ffffff;">重要警告：+++++++++++++++++++++++++++++++++++++++++++++++ + +<br />+<br />+ 在这些编制中，所有的路径都需要于最顶层的NDK目录相对应。<br />+ 例如，如果您有以下设置：<br />+<br />+sources/foo/Android.mk<br />+sources/bar/ Android.mk<br />+ 编译过程中，若要在foo/Android.mk中指定你要添加的路径到bar源代码中，<br />+ 你应该使用<br />+ APP_CFLAGS += -Isources/bar<br />+ 或者交替：<br />+ APP_CFLAGS += -I $（LOCAL_PATH )/../bar<br />+<br />+ 使用&#8217;-l../bar/&#8217;将不会工作，以为它将等同于&#8221;-l$NDK_ROOT/../bar&#8221;<br />++++++++++++++++++++++++++++++++++++++++++++++++++ +++++++++++++++++++++<br />注意：在Android的NDK 1.5_r1，只适用于C源文件，而不适合C++。<br />这已得到纠正，以建立完整相匹配的Andr??oid系统。</p><p style="line-height: 28px; margin: 0px 0px 10px; padding: 0px; color: #333333; font-family: 'Hiragino Sans GB W3', 'Hiragino Sans GB', Arial, Helvetica, simsun, u5b8bu4f53; font-size: 16px; background-color: #ffffff;">APP_CXXFLAGS<br />APP_CPPFLAGS的别名，已经考虑在将在未来的版本中废除了</p><p style="line-height: 28px; margin: 0px 0px 10px; padding: 0px; color: #333333; font-family: 'Hiragino Sans GB W3', 'Hiragino Sans GB', Arial, Helvetica, simsun, u5b8bu4f53; font-size: 16px; background-color: #ffffff;">APP_CPPFLAGS<br />当编译的只有C++源文件的时候，可以通过这个C++编译器来设置</p><p style="line-height: 28px; margin: 0px 0px 10px; padding: 0px; color: #333333; font-family: 'Hiragino Sans GB W3', 'Hiragino Sans GB', Arial, Helvetica, simsun, u5b8bu4f53; font-size: 16px; background-color: #ffffff;">注意：在Android NDK-1.5_r1中，这个标志可以应用于C和C++源文件中。并且得到了纠正，以建立完整的与系统相匹配的Android编译系统。你先可也可以使用APP_CFLAGS来应用于C或者C++源文件中。<br />建议使用APP_CFLAGS</p><p style="line-height: 28px; margin: 0px 0px 10px; padding: 0px; color: #333333; font-family: 'Hiragino Sans GB W3', 'Hiragino Sans GB', Arial, Helvetica, simsun, u5b8bu4f53; font-size: 16px; background-color: #ffffff;">APP_BUILD_SCRIPT<br />默认情况下，NDK编译系统会在$(APP_PROJECT_PATH)/jni目录下寻找名为Android.mk文件：<br />$(APP_PROJECT_PATH)/jni/Android.mk</p><p style="line-height: 28px; margin: 0px 0px 10px; padding: 0px; color: #333333; font-family: 'Hiragino Sans GB W3', 'Hiragino Sans GB', Arial, Helvetica, simsun, u5b8bu4f53; font-size: 16px; background-color: #ffffff;">如果你想覆盖此行为，你可以定义APP_BUILD_SCRIPT来指定一个备用的编译脚本。一个非绝对路径总是被解释为相对于NDK的顶层的目录。</p><p style="line-height: 28px; margin: 0px 0px 10px; padding: 0px; color: #333333; font-family: 'Hiragino Sans GB W3', 'Hiragino Sans GB', Arial, Helvetica, simsun, u5b8bu4f53; font-size: 16px; background-color: #ffffff;">APP_ABI<br />默认情况下，NDK的编译系统回味&#8221;armeabi&#8221;ABI生成机器代码。喜爱哪个相当于一个基于CPU可以进行浮点运算的ARMv5TE。你可以使用APP_ABI来选择一个不同的ABI。</p><p style="line-height: 28px; margin: 0px 0px 10px; padding: 0px; color: #333333; font-family: 'Hiragino Sans GB W3', 'Hiragino Sans GB', Arial, Helvetica, simsun, u5b8bu4f53; font-size: 16px; background-color: #ffffff;">比如：为了在ARMv7的设备上支持硬件FPU指令。可以使用<br />APP_ABI := armeabi-v7a</p><p style="line-height: 28px; margin: 0px 0px 10px; padding: 0px; color: #333333; font-family: 'Hiragino Sans GB W3', 'Hiragino Sans GB', Arial, Helvetica, simsun, u5b8bu4f53; font-size: 16px; background-color: #ffffff;">或者为了支持IA-32指令集，可以使用<br />APP_ABI := x86</p><p style="line-height: 28px; margin: 0px 0px 10px; padding: 0px; color: #333333; font-family: 'Hiragino Sans GB W3', 'Hiragino Sans GB', Arial, Helvetica, simsun, u5b8bu4f53; font-size: 16px; background-color: #ffffff;">或者为了同时支持这三种，可以使用<br />APP_ABI := armeabi armeabi-v7a x86</p><p style="line-height: 28px; margin: 0px 0px 10px; padding: 0px; color: #333333; font-family: 'Hiragino Sans GB W3', 'Hiragino Sans GB', Arial, Helvetica, simsun, u5b8bu4f53; font-size: 16px; background-color: #ffffff;">APP_STL<br />默认情况下，NDK的编译系统为最小的C++运行时库（/system/lib/libstdc++.so）提供C++头文件。<br />然而，NDK的C++的实现，可以让你使用或着链接在自己的应用程序中。<br />例如：<br />APP_STL := stlport_static&nbsp;&nbsp;&nbsp; &#8211;&gt; static STLport library<br />APP_STL := stlport_shared&nbsp;&nbsp;&nbsp; &#8211;&gt; shared STLport library<br />APP_STL := system&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &#8211;&gt; default C++ runtime library</p><p style="line-height: 28px; margin: 0px 0px 10px; padding: 0px; color: #333333; font-family: 'Hiragino Sans GB W3', 'Hiragino Sans GB', Arial, Helvetica, simsun, u5b8bu4f53; font-size: 16px; background-color: #ffffff;">下面是一个Application.mk文件的示例：<br />APP_PROJECT_PATH := &lt;path to project&gt;</p><img src ="http://www.cppblog.com/xkjy3000/aggbug/204413.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/xkjy3000/" target="_blank">虚空骄阳</a> 2013-11-24 12:59 <a href="http://www.cppblog.com/xkjy3000/archive/2013/11/24/204413.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Android NDK 开发教程五：Android.mk文件</title><link>http://www.cppblog.com/xkjy3000/archive/2013/11/24/204412.html</link><dc:creator>虚空骄阳</dc:creator><author>虚空骄阳</author><pubDate>Sun, 24 Nov 2013 04:59:00 GMT</pubDate><guid>http://www.cppblog.com/xkjy3000/archive/2013/11/24/204412.html</guid><wfw:comment>http://www.cppblog.com/xkjy3000/comments/204412.html</wfw:comment><comments>http://www.cppblog.com/xkjy3000/archive/2013/11/24/204412.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/xkjy3000/comments/commentRss/204412.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/xkjy3000/services/trackbacks/204412.html</trackback:ping><description><![CDATA[<p style="line-height: 28px; margin: 0px 0px 10px; padding: 0px; color: #333333; font-family: 'Hiragino Sans GB W3', 'Hiragino Sans GB', Arial, Helvetica, simsun, u5b8bu4f53; font-size: 16px; background-color: #ffffff;">NDK项目一个重要组成是它的make 文件 &#8211;android.mk. 下面部分来自<a rel="nofollow" href="http://hualang.iteye.com/blog/1140414" style="text-decoration: none; color: #556c88;">网络翻译</a>（省得我再翻译了:-).</p><p style="line-height: 28px; margin: 0px 0px 10px; padding: 0px; color: #333333; font-family: 'Hiragino Sans GB W3', 'Hiragino Sans GB', Arial, Helvetica, simsun, u5b8bu4f53; font-size: 16px; background-color: #ffffff;">注：大部分情况只需参考HelloJni 和twoLibs 的android.mk 文件即可，如果你想搞清楚android.mk 中定义变量的具体含义，可以参考下面翻译。</p><div id="blog_content" style="line-height: 28px; color: #333333; font-family: 'Hiragino Sans GB W3', 'Hiragino Sans GB', Arial, Helvetica, simsun, u5b8bu4f53; font-size: 16px; background-color: #ffffff;"><p style="margin: 0px 0px 10px; padding: 0px;">Android.mk文件语法详述</p><p style="margin: 0px 0px 10px; padding: 0px;">介绍：<br />&#8212;&#8212;&#8212;&#8212;</p><p style="margin: 0px 0px 10px; padding: 0px;">这篇文档是用来描述你的C或C++源文件中Android.mk编译文件的语法的，为了理解她们我们需要您先看完<br />docs/OVERVIEW.html（http://hualang.iteye.com/blog/1135105）文件来了解它的作用</p><p style="margin: 0px 0px 10px; padding: 0px;">概览：<br />&#8212;&#8212;&#8212;&#8212;<br />Android.mk文件是用来描述build system(编译系统)的，更准确的说：</p><p style="margin: 0px 0px 10px; padding: 0px;">&#8211;该文件是一个微型的GNU Makefile片段，将由build system解析一次或者多次。这样，您就可以尽量减少您声明的变量，并且不要以为在解析过程中没有任何定义。</p><p style="margin: 0px 0px 10px; padding: 0px;">&#8211;这个文件但语法是用来允许你将源文件组织成模块，这个模块中含有：<br />-一个静态库(.a文件)<br />-一个动态库(.so文件)<br />只有动态库才会被安装/复制到你的应用程序包，尽管静态库可以被用来生成动态库。你可以在每个模块中&nbsp; 都定义一个Android.mk文件，你也可以让多个模块共用一个Android.mk文件。</p><p style="margin: 0px 0px 10px; padding: 0px;">&#8211;build system可以为你处理许多细节，例如：你不许要在Android.mk文件中列出头文件或者其他的依赖关系，这些NDK的build system会自动为你计算并处理。</p><p style="margin: 0px 0px 10px; padding: 0px;">这也意味着，当更新到新版本的NDK的时候，你应该得益于新的toolchain/platform的支持，而无需修改你的Android.mk文件。</p><p style="margin: 0px 0px 10px; padding: 0px;">注意：这些语法非常接近于分布在完整的开源的Android源代码中的Android.mk文件，尽管是build system实现的，但是它们的用法是不同的。这样故意设计的决定是为了让应用程序开发者重用&#8220;外部&#8221;库的源代码更容易。</p><p style="margin: 0px 0px 10px; padding: 0px;">简单实例：<br />&#8212;&#8212;&#8212;&#8212;-<br />再详细讲解语法之前，让我们先看看一个简单的例子&#8221;hello JNI&#8221;,它在apps/hello-jni/project下</p><p style="margin: 0px 0px 10px; padding: 0px;">&#8211;&#8217;src&#8217;目录下用于存放java源文件<br />&#8211;&#8216;jni&#8217;目录下用于存放本地源文件，例如&#8221;jni/hello-jni.c&#8221;</p><p style="margin: 0px 0px 10px; padding: 0px;">这个源文件实现了一个简单的共享库(shared library)：实现了一个本地方法，为VM应用程序返回一个字符串。</p><p style="margin: 0px 0px 10px; padding: 0px;">&#8211;&#8216;jni/Android.mk&#8217;文件描述了如何生成一个共享库，它的内容是：<br />&#8212;&#8212;&#8212;&#8212;&#8212;&#8211;Android.mk&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;<br />LOCAL_PATH := $(call my-dir)<br />include $(CLEAR_VARS)</p><p style="margin: 0px 0px 10px; padding: 0px;">LOCAL_MODULE := hello-jni<br />LOCAL_SRC_FILES := hello-jni.c</p><p style="margin: 0px 0px 10px; padding: 0px;">include $(BUILD_SHARED_LIBRARY)<br />&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;<br />现在，让我们分别解释这几行</p><p style="margin: 0px 0px 10px; padding: 0px;">LOCAL_PATH：=$(call my-dir)</p><p style="margin: 0px 0px 10px; padding: 0px;">Android.mk文件必须以LOCAL_PATH变量开始，它用于在树中定位文件。在这个例子中，宏功能&#8217;my-dir&#8217;是由build system提供的，用于返回当前目录路径（包括Android.mk文件本身）</p><p style="margin: 0px 0px 10px; padding: 0px;">include $(CLEAR_VARS)</p><p style="margin: 0px 0px 10px; padding: 0px;">CLEAR_VARS变量是由build system提供的，并且指明了一个GNU makefile文件，这个功能会清理掉所有以LOCAL_开头的内容（例如 LOCAL_MODULE,LOCAL_SRC_FILES,LOCAL_STATIC_LIBRARIES等），除了LOCAL_PATH，这句话是必 须的，因为如果所有的变量都是全局变量的话，所有的可控的编译文件都需要在一个单独的GNU中被解析并执行</p><p style="margin: 0px 0px 10px; padding: 0px;">LOCAL_MODULE :=hello-jni</p><p style="margin: 0px 0px 10px; padding: 0px;">LOCAL_MODULE变量必须被定义，用来区分Android.mk中的每一个模块。文件名必须是唯一的，不能有空格。注意，这里编译器会为你 自动加上一些前缀和后缀，来保证文件是一致的，比如：这里表明一个动态连接库模块被命名为&#8221;hello-jni&#8221;，但是最后会生成为&#8221;libhello- jni.so&#8221;文件。但是在Java中装载这个库的时候还是使用&#8221;hello-jni&#8221;名称。当然如果我们使用&#8221;IMPORTANT NOTE:&#8221;,编译系统就不会为你加上前缀，但是为了支持Android平台源码中的Android.mk文件，也同样会生成libhello- jni.so这样的文件。</p><p style="margin: 0px 0px 10px; padding: 0px;">重要提示：如果你将你的模块命名为&#8217;libfoo&#8217;，编译系统将不会将前缀&#8217;lib&#8217;加上去，并且也会生成libfoo.so文件。</p><p style="margin: 0px 0px 10px; padding: 0px;">LOCAL_SRC_FILES := hello-jni.c</p><p style="margin: 0px 0px 10px; padding: 0px;">LOCAL_SRC_FILES变量被需包括一个C和C++源文件的列表，这些会编译并聚合到一个模块中。<br />注意：这里并不需要你列出头文件和被包含的文件，因为编译系统会自动为你计算相关的属性，源代码中的列表会直接传递给编译器。</p><p style="margin: 0px 0px 10px; padding: 0px;">C++默认文件的扩展名是&#8220;.cpp&#8221;，我们可以通过定义一个LOCAL_DEFAULT_CPP_EXTENSION变量来定义一个不同的C文件。不要忘记在初始化前面的&#8220;.&#8221;点（也就是说&#8221;.cpp&#8221;可以正常工作，但是cpp不能正常工作）</p><p style="margin: 0px 0px 10px; padding: 0px;">include $(BUILD_SHARED_LIBRARY)<br />BUILD_SHARED_LIBRARY这个变量是由系统提供的，并且指定给GNU Makefile的脚本，它可以收集所有你定义的&#8221;include $(CLEAR_VARS)&#8221;中以LOCAL_开头的变量，并且决定哪些要被编译，哪些应该做的更加准确。编译生成的是 以&#8221;lib&lt;module_name&gt;.so&#8221;的文件，这个就是共享库了。我们同样也可以使用BUILD_STATIC_LIBRARY编译 系统便会生成一个以&#8221;lib&lt;module_name&gt;.a&#8221;的文件来供动态库调用。</p><p style="margin: 0px 0px 10px; padding: 0px;">在samples目录下有很多复杂的例子，那里的Android.mk文件可以供我们参考</p><p style="margin: 0px 0px 10px; padding: 0px;">参考：<br />&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8211;<br />这是个变量的列表，你可以依赖或者定义它们到Android.mk中。你可以定义自己使用的其他变量，但是NDK辨析系统只保留了以下名字：</p><p style="margin: 0px 0px 10px; padding: 0px;">&#8211;以LOCAL_开头的名称（如：LOCAL_MODULE）<br />&#8211;以PRIVATE_、NDK_、或APP_（内部使用）开始的名称<br />&#8211;小写的名称（例如&#8217;my-dir&#8217;，内部使用）</p><p style="margin: 0px 0px 10px; padding: 0px;">如果你需要在Android.mk中定义自己的变量的话，我们建议使用MY-前缀，一个简单的例子：<br />&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;-<br />MY_SOURCES := foo.c<br />ifneq($(MY_CONFIG_BAR),)<br />MY_SOURCES += bar.c<br />endif</p><p style="margin: 0px 0px 10px; padding: 0px;">LOCAL_SRC_FILES +=$(MY_SOURCES)<br />&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;-</p><p style="margin: 0px 0px 10px; padding: 0px;">我们继续：</p><p style="margin: 0px 0px 10px; padding: 0px;">NDK提供的变量：<br />在您的Android.mk文件被解析之前这些GNU Make变量由编译系统定义，注意，在某些情况下，NDK可能被解析几次，每次以不同的变量的定义解析的</p><p style="margin: 0px 0px 10px; padding: 0px;">CLEAR_VARS<br />CLEAR_VARS这个变量由系统提供，功能是清理掉所有以LOCAL_开头的内容，再开始一个新的模块之前，你必须包括这段脚本</p><p style="margin: 0px 0px 10px; padding: 0px;">include ($CLEAR_VARS)</p><p style="margin: 0px 0px 10px; padding: 0px;">BUILD_SHARED_LIBRARY</p><p style="margin: 0px 0px 10px; padding: 0px;">在编译脚本中收集所有以LOCAL_开头的信息并且决定从列出的源代码中编译一个目标共享库。注意，你必须定义了LOCAL_MODULE和LOCAL_SRC_FILES变量，使用它的时候，可以这样定义</p><p style="margin: 0px 0px 10px; padding: 0px;">include $(BUILD_SHARED_LIBRARY)</p><p style="margin: 0px 0px 10px; padding: 0px;">注意，我们会生成一个以lib&lt;module_name&gt;.so为名的文件</p><p style="margin: 0px 0px 10px; padding: 0px;">BUILD_STATIC_LIBRARY</p><p style="margin: 0px 0px 10px; padding: 0px;">用来构建一个静态库，该静态库将不会被拷贝到你的project/packages下，但是可以被用于动态库<br />(看下面的LOCAL_STATIC_LIBRARY和LOCAL_WHOLE_STATIC_LIBRARY介绍)</p><p style="margin: 0px 0px 10px; padding: 0px;">例如：<br />include $(BUILD_STATIC_LIBRARY)</p><p style="margin: 0px 0px 10px; padding: 0px;">注意，这将生成一个lib&lt;module_name&gt;.a为名字的模块</p><p style="margin: 0px 0px 10px; padding: 0px;">PREBUILD_SHARED_LIBRARY<br />在编译脚本中用于指定一个预先编译的动态库，不像BUILD_SHARED_LIBRARY和BUILD_STATIC_LIBRARY，LOCAL_SRC_FILES的预先共享库必须是一个单独的路径（如：foo/libfoo.so），而不是源文件。</p><p style="margin: 0px 0px 10px; padding: 0px;">你可以在另一个模块中引用预编译的库（参见docs/pribuilds.html）</p><p style="margin: 0px 0px 10px; padding: 0px;">PRIBUILD_STATIC_LIBRARY<br />这个变量类似于PREBUILD_SHARED_LIBRARY，但是是针对静态库的，(详见docs/prebuilds.html)</p><p style="margin: 0px 0px 10px; padding: 0px;">TARGET_ARCH<br />TARGET_ARCH指框架中CPU的名字已经被Android开源代码明确指出了，这里的arm包含了任何ARM-独立结构的架构，以及每个独立的CPU版本</p><p style="margin: 0px 0px 10px; padding: 0px;">TARGET_PLATFORM<br />Android平台的名字在Android.mk中被解析，比如&#8221;android-3&#8243;对应Android 1.5系统镜像，对于平台的名称对应Android系统的列表，请看docs/STABLE-APIS.html</p><p style="margin: 0px 0px 10px; padding: 0px;">TARGET_ARCH_ABI<br />在Android.mk中被解析时指CPU+ABI的名字。</p><p style="margin: 0px 0px 10px; padding: 0px;">目前支持的两个值<br />armeabi for ARMv5TE<br />armeabi-v7a</p><p style="margin: 0px 0px 10px; padding: 0px;">注意，到Android NDK 1.6_r1，这个值被简化为&#8221;arm&#8221;。然而，这个值被重定义可以更好的匹配Android平台内部使用的是什么</p><p style="margin: 0px 0px 10px; padding: 0px;">更多的信息可以参见docs/CPU-ARCH-ABIS.html</p><p style="margin: 0px 0px 10px; padding: 0px;">未来的NDK版本中得到支持，它们会有一个不同的名字，注意所有基于ARM的ABI都会有一个&#8221;TARGET_ARCH&#8221;被定义给arm，但也有可能有不同的&#8221;TARGET_ARCH_ABI&#8221;</p><p style="margin: 0px 0px 10px; padding: 0px;">TARGET_ABI</p><p style="margin: 0px 0px 10px; padding: 0px;">目标平台和ABI的链接，这里要定义$(TARGET_PLATFORM)-$(TARGET_ARCH_ABI)它们都非常有用，特别是当你想测试一下具体的系统镜像在一个真实设备环境的时候</p><p style="margin: 0px 0px 10px; padding: 0px;">默认地，这个是&#8221;android-3-armeabi&#8221;</p><p style="margin: 0px 0px 10px; padding: 0px;">(到Android NDK 16_R1版本，使用&#8221;android-3-arm&#8221;作为默认)</p><p style="margin: 0px 0px 10px; padding: 0px;">NDK提供的宏功能<br />&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8211;<br />以下是使用GNU make的宏功能，必须通过使用&#8221;$(call &lt;function&gt;)&#8221;，返回一个文本信息。</p><p style="margin: 0px 0px 10px; padding: 0px;">my-dir</p><p style="margin: 0px 0px 10px; padding: 0px;">返回最后包含的makefile的路径，这通常是当前Android.mk所在目录的路径，在Android.mk开始之前定义<br />LOCAL&#8212;&#8212;PATH是很有用的。</p><p style="margin: 0px 0px 10px; padding: 0px;">在Android.mk文件的开始位置定义<br />LOCAL_PATH :=$(call my-dir)</p><p style="margin: 0px 0px 10px; padding: 0px;">&#8230;声明一个模块<br />include $(LOCAL_PATH)/foo/Android.mk</p><p style="margin: 0px 0px 10px; padding: 0px;">LOCAL_PATH :=($call my-dir)</p><p style="margin: 0px 0px 10px; padding: 0px;">&#8230;声明另一个模块<br />这里的问题是第二次调用&#8221;my-dir&#8221;定义LOCAL_PATH替换$PATH为$PATH/foo，由于在此之前执行过。</p><p style="margin: 0px 0px 10px; padding: 0px;">对于这个原因，最好是将额外的其他所有东西都在Android.mk中包含进来</p><p style="margin: 0px 0px 10px; padding: 0px;">LOCAL_PATH :=$(call my-dir)</p><p style="margin: 0px 0px 10px; padding: 0px;">&#8230;声明一个模块</p><p style="margin: 0px 0px 10px; padding: 0px;">LOCAL_PATH :=$(call my-dir)<br />&#8230;声明另一个模块</p><p style="margin: 0px 0px 10px; padding: 0px;">#在Android.mk的最后额外包括进来<br />include $(LOCAL_PATH)/foo/Android.mk</p><p style="margin: 0px 0px 10px; padding: 0px;">如果这样不方便的话，保存第一个my-dir调用的值到另一个变量中，例如</p><p style="margin: 0px 0px 10px; padding: 0px;">MY_LOCAL_PATH :=$(call my-dir)<br />LOCAL_PATH :=$(MY_LOCAL_PATH)<br />&#8230;声明一个模块</p><p style="margin: 0px 0px 10px; padding: 0px;">include $(LOCAL_PATH)/foo/Android.mk<br />LOCAL_PATH :=$(MY_LOCAL_PATH)<br />&#8230;声明另一个模块</p><p style="margin: 0px 0px 10px; padding: 0px;">all-subdir-makefiles<br />返回一个Android.mk文件所在位置的列表，以及当前的my-dir的路径。比如<br />sources/foo/Android.mk<br />sources/foo/lib1/Android.mk<br />sources/foo/lib2/Android.mk</p><p style="margin: 0px 0px 10px; padding: 0px;">如果sources/foo/Android.mk包含了这行语句<br />include $(call all-subdir-makefiles)</p><p style="margin: 0px 0px 10px; padding: 0px;">那么，它将会自动将sources/foo/lib1/Android.mk和sources/foo/lib2/Android.mk包含进来。</p><p style="margin: 0px 0px 10px; padding: 0px;">此功能可以用于提供深层嵌套的源代码目录build system的层次结构。请注意，默认情况下，NDK只会寻找<br />sources/*Android.mk</p><p style="margin: 0px 0px 10px; padding: 0px;">this-makefile<br />返回当前makefile的路径（也就是那个功能被调用了）</p><p style="margin: 0px 0px 10px; padding: 0px;">parent-makefile<br />返回makefile的包含树，也就是包含Makefile当前的文件</p><p style="margin: 0px 0px 10px; padding: 0px;">grand-parent-makefile<br />你猜？</p><p style="margin: 0px 0px 10px; padding: 0px;">import-module<br />一个允许你通过名字找到并包含另一个模块的的Android.mk的功能，例如</p><p style="margin: 0px 0px 10px; padding: 0px;">$(call import-module,&lt;name&gt;)</p><p style="margin: 0px 0px 10px; padding: 0px;">这将会找到通过NDK_MODULE_PATH环境变量引用的模块&lt;name&gt;的目录列表，并且将其自动包含到<br />Android.mk中</p><p style="margin: 0px 0px 10px; padding: 0px;">详细信息请参阅:docs/IMPORT-MODULE.html</p><p style="margin: 0px 0px 10px; padding: 0px;">模块变量描述：<br />&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;-<br />下面的这些变量是用来描述怎样用你的模块来编译系统的。你可以定义它们中的一些比如<br />&#8220;include $(CLEAR_VARS)&#8221;和&#8221;include $(BUILD_XXX)&#8221;，正如前面所写的，$(CLEAR_VARS)是一个可以取消定义/清楚所有变量的脚本。</p><p style="margin: 0px 0px 10px; padding: 0px;">LOCAL_PATH<br />这个变量是用来给出当前文件的路径。您比系再您的Android.mk开始位置定义：<br />LOCAL_PATH :=$(call my-dir)<br />注意，这个变量是不被$(CLEAR_VARS)清除的，其他的都要被清除（我们可以定义几个模块到一个文件中）</p><p style="margin: 0px 0px 10px; padding: 0px;">LOCAL_MODULE<br />这个是你模块的名称，它在你的所有模块中名称必须是唯一的，并且不能包含空格。你必须在包含任何<br />$(BUILD-XXX)脚本之前定义它。</p><p style="margin: 0px 0px 10px; padding: 0px;">默认情况下，模块的名称决定了生成的文件的名称，例如lib&lt;foo&gt;.so，它是foo模块的名字。</p><p style="margin: 0px 0px 10px; padding: 0px;">你可以用LOCAL_MODULE_FILENAME覆盖默认的那一个</p><p style="margin: 0px 0px 10px; padding: 0px;">LOCAL_MODULE_FILENAME</p><p style="margin: 0px 0px 10px; padding: 0px;">这个变量是可选的，并且允许你重新定义生成文件的名字。默认的，模块&lt;foo&gt;将始终生成lib&lt;foo&gt;.a或者lib&lt;foo&gt;.so文件，这是标准的UNIX公约</p><p style="margin: 0px 0px 10px; padding: 0px;">你可以通过LOCAL_MODULE_FILENAME覆盖它</p><p style="margin: 0px 0px 10px; padding: 0px;">LOCAL_MODULE :=foo-version-1<br />LOCAL_MODULE_FILENAME :=libfoo<br />注意：你不能将文件路径或者文件扩展名写到LOCAL_MODULE_FILENAME里，这些将有build system自动处理。</p><p style="margin: 0px 0px 10px; padding: 0px;">LOCAL_SRC_FILES<br />这是你模块中将要编译的源文件列表。只列出将被传递到编译器的文件，因为build system自动为您计算了它们的依赖。</p><p style="margin: 0px 0px 10px; padding: 0px;">注意：源文件的名称都是相对LOCAL_PATH的，您可以使用路径组件，例如<br />LOCAL_SRC_FILES :=foo.c\<br />toto/bar.c</p><p style="margin: 0px 0px 10px; padding: 0px;">注意：在build system时请务必使用UNIX风格的斜杠(/)，windows风格的斜杠将不会得到处理</p><p style="margin: 0px 0px 10px; padding: 0px;">LOCAL_CPP_EXTENSION<br />这是个可选的变量，可以被定义为文件扩展名为c++的源文件，默认是&#8221;.cpp&#8221;，但是你可以改变它，比如</p><p style="margin: 0px 0px 10px; padding: 0px;">LOCAL_CPP_EXTENSION:=.cxx</p><p style="margin: 0px 0px 10px; padding: 0px;">LOCAL_C_INCLUDES</p><p style="margin: 0px 0px 10px; padding: 0px;">可选的路径列表，相对于NDK的根目录，当编译所有的源文件（C、C++、或者汇编）时将被追加到搜索路径中<br />例如：<br />LOCAL_C_INCLUDES:=sources/foo<br />或者<br />LOCAL_C_INCLUDES:=$(LOCAL_PATH)/../foo</p><p style="margin: 0px 0px 10px; padding: 0px;">这些都在任何相应列入标志之前被放置在<br />LOCAL_CFLAGS / LOCAL_CPPFLAGS</p><p style="margin: 0px 0px 10px; padding: 0px;">当用用ndk-gdb启动本机调试时，LOCAL_C_INCLUDES也会自动被使用到</p><p style="margin: 0px 0px 10px; padding: 0px;">LOCAL_CFLAGS</p><p style="margin: 0px 0px 10px; padding: 0px;">当编译C/C++源文件时传递一个可选的编译器标志。<br />这对于指定额外的宏定义或编译选项很有用</p><p style="margin: 0px 0px 10px; padding: 0px;">重要提示：尽量不要改变Android.mk中的优化/调试级别，这个可以通过在Application.mk中设置相应的信息来自动为你处理，并且会会让NDK生成在调试过程中使用的有用的数据文件。</p><p style="margin: 0px 0px 10px; padding: 0px;">注意：在Android-ndk-1.5_r1中，只使用于C源文件，而不适用于C++源文件。在匹配所有Android build system的行为已经得到了纠正。（现在你可以为C++源文件使用LOCAL_CPPFLAGS来指定标志）</p><p style="margin: 0px 0px 10px; padding: 0px;">它可以用LOCAL_CFLAGS += -I&lt;path&gt;来指定额外的包含路径，然而，如果使用LOCAL_C_INCLUDES会更好，因为用ndk-gdk进行本地调试的时候，那些路径依然是需要使用的</p><p style="margin: 0px 0px 10px; padding: 0px;">LOCAL_CXXFLAGS<br />LOCAL_CPPFLAGS的别名。请注意，这个标志在NDK的未来的版本中将会消失</p><p style="margin: 0px 0px 10px; padding: 0px;">LOCAL_CPPFLAGS<br />当只编译C++源代码的时候，将传递一个可选的编译器标志。它们将会出现再LOCAL_CFLAGS之后。</p><p style="margin: 0px 0px 10px; padding: 0px;">注意：在Android NDK-1.5_r1版本中，相应的标志可以应用于C或C++源文件上。在配合完整的Android build system的时候，这已经得到了纠正。（你可以使用LOCAL_CFLAGS去指定C或C++源文件）</p><p style="margin: 0px 0px 10px; padding: 0px;">LOCAL_STATIC_LIBRARIES</p><p style="margin: 0px 0px 10px; padding: 0px;">静态库模块的列表(通过BUILD_STATIC_LIBRARY创建)应与此模块链接。这仅仅是为了使动态库敏感。</p><p style="margin: 0px 0px 10px; padding: 0px;">LOCAL_SHARED_LIBRARY<br />共享库的列表&#8220;模块&#8221;，这个模块依赖于运行时.这在链接的时候和在生成的文件中嵌入相应的信息是非常必要的</p><p style="margin: 0px 0px 10px; padding: 0px;">LOCAL_WHOLE_STATIC_LIBRARIES</p><p style="margin: 0px 0px 10px; padding: 0px;">LOCAL_WHOLE_STATIC_LIBRARIES是一个用于表示相应的库模块被用作为&#8220;整个档案&#8221;到链接程序的变量。</p><p style="margin: 0px 0px 10px; padding: 0px;">当几个静态库之间有循环依赖关系的时候，通常是很有益的。注意，当用来编译一个动态库的时候，这将迫使你将所有的静态库中的对象文件添加到最终的二进制文件中。但生成可执行程序时，这是不确定的。</p><p style="margin: 0px 0px 10px; padding: 0px;">LOCAL_LDLIBS<br />当额外的链接标志列表被用于在编译你的模块时，通过用&#8221;-l&#8221;前缀的特定系统库传递名字是很有用的。例如，下面的旧爱哪个告诉你生成一个在加载时链接到/system/lib/libz.so的模块。</p><p style="margin: 0px 0px 10px; padding: 0px;">LOCAL_LDLIBS :=-lz</p><p style="margin: 0px 0px 10px; padding: 0px;">LOCAL_ALLOW_UNDEFINED_SYMBOLS<br />默认情况下，当试图编译一个共享库的时候遇到任何未定义的引用都可能导致&#8221;未定义符号&#8221;(undefined symbol)的错误。这在你的源代码中捕获bug会很有用。</p><p style="margin: 0px 0px 10px; padding: 0px;">然而，但是由于某些原因，你需要禁用此检查的话，设置变量为&#8221;true&#8221;即可。需要注意的是，相应的共享库在运行时可能加载失败。</p><p style="margin: 0px 0px 10px; padding: 0px;">LOCAL_ARM_MODE<br />默认情况下，在&#8221;thumb&#8221;模式下会生成ARM目标二进制，其中每个指令都是16位宽。你可以定义这个变量为&#8221;arm&#8221;，如果你想在&#8221;arm&#8221;模式下（32位指令）强迫模块对象文件的生成。例如：</p><p style="margin: 0px 0px 10px; padding: 0px;">LOCAL_ARM_MODE := arm</p><p style="margin: 0px 0px 10px; padding: 0px;">注意，你需要执行编译系统为在ARM模式下通过文件的名字增加后缀的方式编译指定的源文件。比如：</p><p style="margin: 0px 0px 10px; padding: 0px;">LOCAL_SRC_FILES :=foo.c bar.c.arm</p><p style="margin: 0px 0px 10px; padding: 0px;">这会告诉编译系统一直以ARM模式编译&#8221;bar.c&#8221;,并且通过LOCAL_ARM_MODE的值编译foo.c。</p><p style="margin: 0px 0px 10px; padding: 0px;">注意：在Application.mk文件中设置APP_OPTIM为&#8221;debug&#8221;也会强制ARM二进制文件的生成。这是因为工具链调试其中的bug不会处理thumb代码。</p><p style="margin: 0px 0px 10px; padding: 0px;">LOCAL_ARM_NEON</p><p style="margin: 0px 0px 10px; padding: 0px;">定义这个变量为&#8221;true&#8221;会允许在你的C或C++源文件的GCC的内部函数中使用ARM高级SIMD（又名NEON），以及在聚合文件中的NEON指令。</p><p style="margin: 0px 0px 10px; padding: 0px;">当针对&#8221;armeabi-v7a&#8221;ABI对应的ARMv7指令集时你应该定义它。注意，并不是所有的ARMv7都是基于NEON指令集扩展的CPU，你应该执行运行时来检测在运行时中这段代码的安全。</p><p style="margin: 0px 0px 10px; padding: 0px;">另外，你也可以指定特定的源文件，比如用支持NEON&#8221;.neon&#8221;后缀的源文件也可以被编译。</p><p style="margin: 0px 0px 10px; padding: 0px;">LOCAL_SRC_FILES :=foo.c.neon bar.c zoo.c.arm.neon</p><p style="margin: 0px 0px 10px; padding: 0px;">在这个例子中，&#8221;foo.c&#8221;将会被编译在thumb+neon模式中，&#8221;bar.c&#8221;以thumb模式编译，zoo.c以arm+neon模式编译。</p><p style="margin: 0px 0px 10px; padding: 0px;">注意，如果你使用两个的话，&#8221;.neon&#8221;后缀必须出现在&#8221;.arm&#8221;后缀之后<br />（就是foo.c.arm.neon可以工作，但是foo.c.neon.arm不工作）</p><p style="margin: 0px 0px 10px; padding: 0px;">LOCAL_DISABLE_NO_EXECUTE</p><p style="margin: 0px 0px 10px; padding: 0px;">Android NDK r4开始添加了支持&#8221;NX位&#8221;安全功能特性。它是默认启用的，如果你需要的话，可以通过设置变量为&#8220;true&#8221;来禁用它。</p><p style="margin: 0px 0px 10px; padding: 0px;">注意：此功能不修改ABI，并且只在ARMv6及以上的CPU设备的内核上被启用。</p><p style="margin: 0px 0px 10px; padding: 0px;">更多信息，可以参见：</p><p style="margin: 0px 0px 10px; padding: 0px;">http://en.wikipedia.org/wiki/NX_bit</p><p style="margin: 0px 0px 10px; padding: 0px;">http://www.gentoo.org/proj/en/hardened/gnu-stack.xml</p><p style="margin: 0px 0px 10px; padding: 0px;">LOCAL_EXPORT_CFLAGS</p><p style="margin: 0px 0px 10px; padding: 0px;">定义这个变量用来记录C/C++编译器标志集合，并且会被添加到其他任何以LOCAL_STATIC_LIBRARIES和LOCAL_SHARED_LIBRARIES的模块的LOCAL_CFLAGS定义中。</p><p style="margin: 0px 0px 10px; padding: 0px;">例如：这样定义&#8221;foo&#8221;模块<br />include $(CLEAR_VARS)<br />LOCAL_MODULE :=foo<br />LOCAL_SRC_FILES :=foo/foo.c<br />LOCAL_EXPORT_CFLAGS :=-DFOO=1<br />include $(BUILD_STATIC_LIBRARY)</p><p style="margin: 0px 0px 10px; padding: 0px;">另一个模块，叫做&#8221;bar&#8221;，并且依赖于上面的模块<br />include $(CLEAR_VARS)<br />LOCAL_MODULE :=bar<br />LOCAL_SRC_FILES :=bar.c<br />LOCAL_CFLAGS:=-DBAR=2<br />LOCAL_STATIC_LIBRARIES:=foo<br />include $(BUILD_SHARED_LIBRARY)</p><p style="margin: 0px 0px 10px; padding: 0px;">然后，当编译bar.c的时候，标志&#8221;-DFOO=1 -DBAR=2&#8243;将被传递到编译器。</p><p style="margin: 0px 0px 10px; padding: 0px;">输出的标志被添加到模块的LOCAL_CFLAGS上，所以你可以很容易复写它们。它们也有传递性：如果&#8221;zoo&#8221;依赖&#8221;bar&#8221;，&#8220;bar&#8221;依赖&#8221;foo&#8221;，那么&#8221;zoo&#8221;也将继承&#8221;foo&#8221;输出的所有标志。</p><p style="margin: 0px 0px 10px; padding: 0px;">最后，当编译模块输出标志的时候，这些标志并不会被使用。在上面的例子中，当编译foo/foo.c时，<br />-DFOO=1将不会被传递给编译器。</p><p style="margin: 0px 0px 10px; padding: 0px;">LOCAL_EXPORT_CPPFLAGS</p><p style="margin: 0px 0px 10px; padding: 0px;">类似LOCAL_EXPORT_CFLAGS,但适用于C++标志。</p><p style="margin: 0px 0px 10px; padding: 0px;">LOCAL_EXPORT_C_INCLUDES</p><p style="margin: 0px 0px 10px; padding: 0px;">类似LOCAL_EXPORT_C_CFLAGS,但是只有C能包含路径，如果&#8221;bar.c&#8221;想包含一些由&#8221;foo&#8221;模块提供的头文件的时候这会很有用。</p><p style="margin: 0px 0px 10px; padding: 0px;">LOCAL_EXPORT_LDLIBS</p><p style="margin: 0px 0px 10px; padding: 0px;">类似于LOCAL_EXPORT_CFLAGS,但是只用于链接标志。注意，引入的链接标志将会被追加到模块的LOCAL_LDLIBS，这是因为UNIX连接器的工作方式。</p><p style="margin: 0px 0px 10px; padding: 0px;">当模块foo是一个静态库的时候并且代码依赖于系统库时会很有用的。LOCAL_EXPORT_LDLIBS可以用于输出依赖，例如：</p><p style="margin: 0px 0px 10px; padding: 0px;">include $(CLEAR_VARS)<br />LOCAL_MODULE := foo<br />LOCAL_SRC_FILES := foo/foo.c<br />LOCAL_EXPORT_LDLIBS := -llog<br />include $(BUILD_STATIC_LIBRARY)</p><p style="margin: 0px 0px 10px; padding: 0px;">include $(CLEAR_VARS)<br />LOCAL_MODULE := bar<br />LOCAL_SRC_FILES := bar.c<br />LOCAL_STATIC_LIBRARIES := foo<br />include $(BUILD_SHARED_LIBRARY)</p><p style="margin: 0px 0px 10px; padding: 0px;">这里，在连接器命令最后，libbar.so将以-llog参数进行编译来表明它依赖于系统日志库，因为它依赖于foo。</p><p style="margin: 0px 0px 10px; padding: 0px;">LOCAL_FILTER_ASM</p><p style="margin: 0px 0px 10px; padding: 0px;">这个变量定义了一个shell命令，将用于过滤，从你的LOCAL_SRC_FILES中产生的或者聚合文件。</p><p style="margin: 0px 0px 10px; padding: 0px;">当它被定义了，将会出现如下的情况：</p><p style="margin: 0px 0px 10px; padding: 0px;">&#8211;任何C或C++源文件将会生成到一个临时的聚合的文件中（而不是被编译成目标文件）<br />&#8211;任何临时聚合文件，任何在LOCAL_SRC_FILES中列出的聚合文件将通过LOCAL_FILER_ASM命令生成另一个临时聚合文件</p><p style="margin: 0px 0px 10px; padding: 0px;">&#8211;这些过滤聚合文件被编译成目标文件。</p><p style="margin: 0px 0px 10px; padding: 0px;">换种说法，如果<br />LOCAL_SRC_FILES&nbsp; := foo.c bar.S<br />LOCAL_FILTER_ASM := myasmfilter</p><p style="margin: 0px 0px 10px; padding: 0px;">foo.c &#8211;1&#8211;&gt; $OBJS_DIR/foo.S.original &#8211;2&#8211;&gt; $OBJS_DIR/foo.S &#8211;3&#8211;&gt; $OBJS_DIR/foo.o<br />bar.S&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &#8211;2&#8211;&gt; $OBJS_DIR/bar.S &#8211;3&#8211;&gt; $OBJS_DIR/bar.o</p><p style="margin: 0px 0px 10px; padding: 0px;">&#8220;1&#8221;对应的编译器，&#8220;2&#8221;的过滤器，和&#8220;3&#8221;的汇编。过滤器必须是一个独立的shell命令作为第一个参数输入文件的名称，和输出的名称第二，如文件为：</p><p style="margin: 0px 0px 10px; padding: 0px;">myasmfilter$ OBJS_DIR/ foo.S.original$ OBJS_DIR/ foo.S<br />myasmfilter bar.S$ OBJS_DIR/ bar.S</p></div><img src ="http://www.cppblog.com/xkjy3000/aggbug/204412.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/xkjy3000/" target="_blank">虚空骄阳</a> 2013-11-24 12:59 <a href="http://www.cppblog.com/xkjy3000/archive/2013/11/24/204412.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Android NDK 开发教程四：TwoLibs示例</title><link>http://www.cppblog.com/xkjy3000/archive/2013/11/24/204411.html</link><dc:creator>虚空骄阳</dc:creator><author>虚空骄阳</author><pubDate>Sun, 24 Nov 2013 04:58:00 GMT</pubDate><guid>http://www.cppblog.com/xkjy3000/archive/2013/11/24/204411.html</guid><wfw:comment>http://www.cppblog.com/xkjy3000/comments/204411.html</wfw:comment><comments>http://www.cppblog.com/xkjy3000/archive/2013/11/24/204411.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/xkjy3000/comments/commentRss/204411.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/xkjy3000/services/trackbacks/204411.html</trackback:ping><description><![CDATA[<span style="color: #333333; font-family: 'Hiragino Sans GB W3', 'Hiragino Sans GB', Arial, Helvetica, simsun, u5b8bu4f53; font-size: 16px; line-height: 28px; background-color: #ffffff;">随Android NDK 提供的另外一个例子TwoLibs，其中有两个库，一个为动态库,一个为静态库，最终供Android Application使用的动态库使用静态库中的函数，如下图所示：<br /></span><img src="http://www.cppblog.com/images/cppblog_com/xkjy3000/DDD.png" width="349" height="362" align="absMiddle" alt="" /><br /><br /><p style="line-height: 28px; margin: 0px 0px 10px; padding: 0px; color: #333333; font-family: 'Hiragino Sans GB W3', 'Hiragino Sans GB', Arial, Helvetica, simsun, u5b8bu4f53; font-size: 16px; background-color: #ffffff;">其中在first.c 中定义了一个简单的C函数</p><pre title="" style="line-height: 28px; white-space: pre-wrap; color: #333333; font-size: 16px; background-color: #ffffff;">int first(int x, int y)<br />{<br /> return x+y;<br />} </pre><p style="line-height: 28px; margin: 0px 0px 10px; padding: 0px; color: #333333; font-family: 'Hiragino Sans GB W3', 'Hiragino Sans GB', Arial, Helvetica, simsun, u5b8bu4f53; font-size: 16px; background-color: #ffffff;">second.c 调用这个函数</p><pre title="" style="line-height: 28px; white-space: pre-wrap; color: #333333; font-size: 16px; background-color: #ffffff;">jint<br />Java_com_example_twolibs_TwoLibs_add( JNIEnv*  env,<br /> jobject  this,<br /> jint     x,<br /> jint     y )<br />{<br /> return first(x, y);<br />} </pre><p style="line-height: 28px; margin: 0px 0px 10px; padding: 0px; color: #333333; font-family: 'Hiragino Sans GB W3', 'Hiragino Sans GB', Arial, Helvetica, simsun, u5b8bu4f53; font-size: 16px; background-color: #ffffff;">为了介绍动态库调用静态库的方法，这个例子将两个C文件编译成两个模块，这是通过android.mk 来定义的。</p><p style="line-height: 28px; margin: 0px 0px 10px; padding: 0px; color: #333333; font-family: 'Hiragino Sans GB W3', 'Hiragino Sans GB', Arial, Helvetica, simsun, u5b8bu4f53; font-size: 16px; background-color: #ffffff;">LOCAL_PATH:= $(call my-dir)</p><p style="line-height: 28px; margin: 0px 0px 10px; padding: 0px; color: #333333; font-family: 'Hiragino Sans GB W3', 'Hiragino Sans GB', Arial, Helvetica, simsun, u5b8bu4f53; font-size: 16px; background-color: #ffffff;"># first lib, which will be built statically<br />#<br />include $(CLEAR_VARS)</p><p style="line-height: 28px; margin: 0px 0px 10px; padding: 0px; color: #333333; font-family: 'Hiragino Sans GB W3', 'Hiragino Sans GB', Arial, Helvetica, simsun, u5b8bu4f53; font-size: 16px; background-color: #ffffff;"><span style="color: #0000ff;">LOCAL_MODULE&nbsp;&nbsp;&nbsp; := libtwolib-first</span><br />LOCAL_SRC_FILES := first.c</p><p style="line-height: 28px; margin: 0px 0px 10px; padding: 0px; color: #333333; font-family: 'Hiragino Sans GB W3', 'Hiragino Sans GB', Arial, Helvetica, simsun, u5b8bu4f53; font-size: 16px; background-color: #ffffff;"><span style="color: #0000ff;">include $(BUILD_STATIC_LIBRARY)</span></p><p style="line-height: 28px; margin: 0px 0px 10px; padding: 0px; color: #333333; font-family: 'Hiragino Sans GB W3', 'Hiragino Sans GB', Arial, Helvetica, simsun, u5b8bu4f53; font-size: 16px; background-color: #ffffff;"># second lib, which will depend on and include the first one<br />#<br />include $(CLEAR_VARS)</p><p style="line-height: 28px; margin: 0px 0px 10px; padding: 0px; color: #333333; font-family: 'Hiragino Sans GB W3', 'Hiragino Sans GB', Arial, Helvetica, simsun, u5b8bu4f53; font-size: 16px; background-color: #ffffff;"><span style="color: #0000ff;">LOCAL_MODULE&nbsp;&nbsp;&nbsp; := libtwolib-second</span><br />LOCAL_SRC_FILES := second.c</p><p style="line-height: 28px; margin: 0px 0px 10px; padding: 0px; color: #333333; font-family: 'Hiragino Sans GB W3', 'Hiragino Sans GB', Arial, Helvetica, simsun, u5b8bu4f53; font-size: 16px; background-color: #ffffff;"><span style="color: #0000ff;">LOCAL_STATIC_LIBRARIES := libtwolib-first</span></p><p style="line-height: 28px; margin: 0px 0px 10px; padding: 0px; color: #333333; font-family: 'Hiragino Sans GB W3', 'Hiragino Sans GB', Arial, Helvetica, simsun, u5b8bu4f53; font-size: 16px; background-color: #ffffff;"><span style="color: #0000ff;">include $(BUILD_SHARED_LIBRARY)</span></p><p style="line-height: 28px; margin: 0px 0px 10px; padding: 0px; color: #333333; font-family: 'Hiragino Sans GB W3', 'Hiragino Sans GB', Arial, Helvetica, simsun, u5b8bu4f53; font-size: 16px; background-color: #ffffff;"><span style="color: #0000ff;"><span style="color: #000000;">注：当然对于这个简单的例子，大可不必编译成两个模块。</span></span></p><p style="line-height: 28px; margin: 0px 0px 10px; padding: 0px; color: #333333; font-family: 'Hiragino Sans GB W3', 'Hiragino Sans GB', Arial, Helvetica, simsun, u5b8bu4f53; font-size: 16px; background-color: #ffffff;"><span style="color: #0000ff;"><span style="color: #000000;">在Android 应用中调用动态库（Android应用只可以调用动态库）</span></span></p><pre title="" style="line-height: 28px; white-space: pre-wrap; color: #333333; font-size: 16px; background-color: #ffffff;">public class TwoLibs extends Activity<br />{<br /> /** Called when the activity is first created. */<br /> @Override<br /> public void onCreate(Bundle savedInstanceState)<br /> {<br /> super.onCreate(savedInstanceState);<br /><br /> TextView  tv = new TextView(this);<br /> int       x  = 1000;<br /> int       y  = 42;<br /><br /> // here, we dynamically load the library at runtime<br /> // before calling the native method.<br /> //<br /> System.loadLibrary("twolib-second");<br /><br /> int  z = add(x, y);<br /><br /> tv.setText( "The sum of " + x + " and " + y + " is " + z );<br /> setContentView(tv);<br /> }<br /><br /> public native int add(int  x, int  y);<br />} </pre><p style="line-height: 28px; margin: 0px 0px 10px; padding: 0px; color: #333333; font-family: 'Hiragino Sans GB W3', 'Hiragino Sans GB', Arial, Helvetica, simsun, u5b8bu4f53; font-size: 16px; background-color: #ffffff;">下面就可以使用ndk-build&nbsp; ，编译C代码，然后再使用Eclipse编译Java代码，运行结果如下：<br /><img src="http://www.cppblog.com/images/cppblog_com/xkjy3000/EEE.png" width="168" height="300" align="absMiddle" alt="" /><br /></p><img src ="http://www.cppblog.com/xkjy3000/aggbug/204411.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/xkjy3000/" target="_blank">虚空骄阳</a> 2013-11-24 12:58 <a href="http://www.cppblog.com/xkjy3000/archive/2013/11/24/204411.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Android NDK 开发教程三：Hello JNI 示例</title><link>http://www.cppblog.com/xkjy3000/archive/2013/11/24/204410.html</link><dc:creator>虚空骄阳</dc:creator><author>虚空骄阳</author><pubDate>Sun, 24 Nov 2013 04:55:00 GMT</pubDate><guid>http://www.cppblog.com/xkjy3000/archive/2013/11/24/204410.html</guid><wfw:comment>http://www.cppblog.com/xkjy3000/comments/204410.html</wfw:comment><comments>http://www.cppblog.com/xkjy3000/archive/2013/11/24/204410.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/xkjy3000/comments/commentRss/204410.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/xkjy3000/services/trackbacks/204410.html</trackback:ping><description><![CDATA[<p style="line-height: 28px; margin: 0px 0px 10px; padding: 0px; color: #333333; font-family: 'Hiragino Sans GB W3', 'Hiragino Sans GB', Arial, Helvetica, simsun, u5b8bu4f53; font-size: 16px; background-color: #ffffff;">Android NDK 开发包带有不少例子，一个简单的例子Hello-Jni ，介绍了如何使用Java调用C函数。</p><p style="line-height: 28px; margin: 0px 0px 10px; padding: 0px; color: #333333; font-family: 'Hiragino Sans GB W3', 'Hiragino Sans GB', Arial, Helvetica, simsun, u5b8bu4f53; font-size: 16px; background-color: #ffffff;">1. 可以使用Eclipse的import 将该项目添加到工作目录中.</p><p style="line-height: 28px; margin: 0px 0px 10px; padding: 0px; color: #333333; font-family: 'Hiragino Sans GB W3', 'Hiragino Sans GB', Arial, Helvetica, simsun, u5b8bu4f53; font-size: 16px; background-color: #ffffff;">该项目目录结构如下：</p><p style="line-height: 28px; margin: 0px 0px 10px; padding: 0px; color: #333333; font-family: 'Hiragino Sans GB W3', 'Hiragino Sans GB', Arial, Helvetica, simsun, u5b8bu4f53; font-size: 16px; background-color: #ffffff;">&#9500;&#9472;&#9472; AndroidManifest.xml<br />&#9500;&#9472;&#9472; default.properties<br />&#9500;&#9472;&#9472; hellojni.txt<br />&#9500;&#9472;&#9472;<span style="color: #0000ff;">&nbsp;jni<br />&#9474;&nbsp;&nbsp; &#9500;&#9472;&#9472; Android.mk<br />&#9474;&nbsp;&nbsp; &#9492;&#9472;&#9472; hello-jni.c</span><br />&#9500;&#9472;&#9472; res<br />&#9474;&nbsp;&nbsp; &#9492;&#9472;&#9472; values<br />&#9474;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &#9492;&#9472;&#9472; strings.xml<br />&#9500;&#9472;&#9472; src<br />&#9474;&nbsp;&nbsp; &#9492;&#9472;&#9472; com<br />&#9474;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &#9492;&#9472;&#9472; example<br />&#9474;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &#9492;&#9472;&#9472; hellojni<br />&#9474;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &#9492;&#9472;&#9472; HelloJni.java<br />&#9492;&#9472;&#9472; tests<br />&#9500;&#9472;&#9472; AndroidManifest.xml<br />&#9500;&#9472;&#9472; default.properties<br />&#9492;&#9472;&#9472; src<br />&#9492;&#9472;&#9472; com<br />&#9492;&#9472;&#9472; example<br />&#9492;&#9472;&#9472; HelloJni<br />&#9492;&#9472;&#9472; HelloJniTest.java</p><p style="line-height: 28px; margin: 0px 0px 10px; padding: 0px; color: #333333; font-family: 'Hiragino Sans GB W3', 'Hiragino Sans GB', Arial, Helvetica, simsun, u5b8bu4f53; font-size: 16px; background-color: #ffffff;">上面列出使用NDK开发项目的基本的目录结构，C代码一般放在jni目录下。</p><p style="line-height: 28px; margin: 0px 0px 10px; padding: 0px; color: #333333; font-family: 'Hiragino Sans GB W3', 'Hiragino Sans GB', Arial, Helvetica, simsun, u5b8bu4f53; font-size: 16px; background-color: #ffffff;">2.&nbsp; 编译Native Code</p><p style="line-height: 28px; margin: 0px 0px 10px; padding: 0px; color: #333333; font-family: 'Hiragino Sans GB W3', 'Hiragino Sans GB', Arial, Helvetica, simsun, u5b8bu4f53; font-size: 16px; background-color: #ffffff;">i) 在命令行（Windows 环境下使用Cygwin的命令行） ，将当前目录改动到 &lt;ndk-root&gt;/samples/hello-jni</p><p style="line-height: 28px; margin: 0px 0px 10px; padding: 0px; color: #333333; font-family: 'Hiragino Sans GB W3', 'Hiragino Sans GB', Arial, Helvetica, simsun, u5b8bu4f53; font-size: 16px; background-color: #ffffff;">ii) 生成build.xml</p><p style="line-height: 28px; margin: 0px 0px 10px; padding: 0px; color: #333333; font-family: 'Hiragino Sans GB W3', 'Hiragino Sans GB', Arial, Helvetica, simsun, u5b8bu4f53; font-size: 16px; background-color: #ffffff;">android update project -p . -s&nbsp; (注：Windows下可能需要&nbsp; 使用android.bat )</p><p style="line-height: 28px; margin: 0px 0px 10px; padding: 0px; color: #333333; font-family: 'Hiragino Sans GB W3', 'Hiragino Sans GB', Arial, Helvetica, simsun, u5b8bu4f53; font-size: 16px; background-color: #ffffff;">iii) 编译C代码</p><p style="line-height: 28px; margin: 0px 0px 10px; padding: 0px; color: #333333; font-family: 'Hiragino Sans GB W3', 'Hiragino Sans GB', Arial, Helvetica, simsun, u5b8bu4f53; font-size: 16px; background-color: #ffffff;">cd &lt;ndk-root&gt;/samples/hello-jni</p><p style="line-height: 28px; margin: 0px 0px 10px; padding: 0px; color: #333333; font-family: 'Hiragino Sans GB W3', 'Hiragino Sans GB', Arial, Helvetica, simsun, u5b8bu4f53; font-size: 16px; background-color: #ffffff;">&lt;ndk_root&gt;/ndk-build</p><p style="line-height: 28px; margin: 0px 0px 10px; padding: 0px; color: #333333; font-family: 'Hiragino Sans GB W3', 'Hiragino Sans GB', Arial, Helvetica, simsun, u5b8bu4f53; font-size: 16px; background-color: #ffffff;">3. 下面就可以使用Eclipse 编译运行 Hello Jni.<br /><img src="http://www.cppblog.com/images/cppblog_com/xkjy3000/AAA.png" width="480" height="800" align="absMiddle" alt="" /><br /></p><p style="line-height: 28px; margin: 0px 0px 10px; padding: 0px; color: #333333; font-family: 'Hiragino Sans GB W3', 'Hiragino Sans GB', Arial, Helvetica, simsun, u5b8bu4f53; font-size: 16px; background-color: #ffffff;">编写NDK的一般步骤，</p><p style="line-height: 28px; margin: 0px 0px 10px; padding: 0px; color: #333333; font-family: 'Hiragino Sans GB W3', 'Hiragino Sans GB', Arial, Helvetica, simsun, u5b8bu4f53; font-size: 16px; background-color: #ffffff;">1. 参考Hello-Jni ，修改jni/Android.mk 文件，将所要编译的文件改成自己的文件。</p><p style="line-height: 28px; margin: 0px 0px 10px; padding: 0px; color: #333333; font-family: 'Hiragino Sans GB W3', 'Hiragino Sans GB', Arial, Helvetica, simsun, u5b8bu4f53; font-size: 16px; background-color: #ffffff;">LOCAL_PATH := $(call my-dir)</p><p style="line-height: 28px; margin: 0px 0px 10px; padding: 0px; color: #333333; font-family: 'Hiragino Sans GB W3', 'Hiragino Sans GB', Arial, Helvetica, simsun, u5b8bu4f53; font-size: 16px; background-color: #ffffff;">include $(CLEAR_VARS)</p><p style="line-height: 28px; margin: 0px 0px 10px; padding: 0px; color: #333333; font-family: 'Hiragino Sans GB W3', 'Hiragino Sans GB', Arial, Helvetica, simsun, u5b8bu4f53; font-size: 16px; background-color: #ffffff;"><span style="color: #0000ff;">LOCAL_MODULE&nbsp;&nbsp;&nbsp; := hello-jni<br />LOCAL_SRC_FILES := hello-jni.c</span></p><p style="line-height: 28px; margin: 0px 0px 10px; padding: 0px; color: #333333; font-family: 'Hiragino Sans GB W3', 'Hiragino Sans GB', Arial, Helvetica, simsun, u5b8bu4f53; font-size: 16px; background-color: #ffffff;">include $(BUILD_SHARED_LIBRARY)</p><p style="line-height: 28px; margin: 0px 0px 10px; padding: 0px; color: #333333; font-family: 'Hiragino Sans GB W3', 'Hiragino Sans GB', Arial, Helvetica, simsun, u5b8bu4f53; font-size: 16px; background-color: #ffffff;">2.&nbsp; 定义Native函数，如HelloJni 中</p><p style="line-height: 28px; margin: 0px 0px 10px; padding: 0px; color: #333333; font-family: 'Hiragino Sans GB W3', 'Hiragino Sans GB', Arial, Helvetica, simsun, u5b8bu4f53; font-size: 16px; background-color: #ffffff;">public native String&nbsp; stringFromJNI();</p><p style="line-height: 28px; margin: 0px 0px 10px; padding: 0px; color: #333333; font-family: 'Hiragino Sans GB W3', 'Hiragino Sans GB', Arial, Helvetica, simsun, u5b8bu4f53; font-size: 16px; background-color: #ffffff;">3. 在Eclipse中编译该项目，注意此时，你无需定义对于的Native文件中C函数，因为手工定义对于的C函数很容易出错，可以借助j<a rel="nofollow" href="http://docs.oracle.com/javase/1.4.2/docs/tooldocs/windows/javah.html" style="text-decoration: none; color: #556c88;">avah</a>&nbsp;工具来完成（包括在JDK中）。</p><p style="line-height: 28px; margin: 0px 0px 10px; padding: 0px; color: #333333; font-family: 'Hiragino Sans GB W3', 'Hiragino Sans GB', Arial, Helvetica, simsun, u5b8bu4f53; font-size: 16px; background-color: #ffffff;">4. 使用Javah 生成对应C函数定义</p><p style="line-height: 28px; margin: 0px 0px 10px; padding: 0px; color: #333333; font-family: 'Hiragino Sans GB W3', 'Hiragino Sans GB', Arial, Helvetica, simsun, u5b8bu4f53; font-size: 16px; background-color: #ffffff;">在命令行下&nbsp; 运行 javah com.example.hellojni.<span style="color: #0000ff;">HelloJni</span></p><p style="line-height: 28px; margin: 0px 0px 10px; padding: 0px; color: #333333; font-family: 'Hiragino Sans GB W3', 'Hiragino Sans GB', Arial, Helvetica, simsun, u5b8bu4f53; font-size: 16px; background-color: #ffffff;"><span style="color: #0000ff;">其中</span>com.example.hellojni 为包名，注意运行Javah 的当前目录 为 &lt;ndk&gt;/examples/hello-jni/bin/classes (你也可以使用javah 的选项来指定classpath).</p><p style="line-height: 28px; margin: 0px 0px 10px; padding: 0px; color: #333333; font-family: 'Hiragino Sans GB W3', 'Hiragino Sans GB', Arial, Helvetica, simsun, u5b8bu4f53; font-size: 16px; background-color: #ffffff;">正确运行好，Javah产生 com_example_hellojni_HelloJni.h</p><p style="line-height: 28px; margin: 0px 0px 10px; padding: 0px; color: #333333; font-family: 'Hiragino Sans GB W3', 'Hiragino Sans GB', Arial, Helvetica, simsun, u5b8bu4f53; font-size: 16px; background-color: #ffffff;">定义如下：</p><pre title="" style="line-height: 28px; white-space: pre-wrap; color: #333333; font-size: 16px; background-color: #ffffff;">/* DO NOT EDIT THIS FILE - it is machine generated */<br />#include &lt;jni.h&gt;<br />/* Header for class com_example_hellojni_HelloJni */<br /><br />#ifndef _Included_com_example_hellojni_HelloJni<br />#define _Included_com_example_hellojni_HelloJni<br />#ifdef __cplusplus<br />extern "C" {<br />#endif<br />/*<br /> * Class:     com_example_hellojni_HelloJni<br /> * Method:    stringFromJNI<br /> * Signature: ()Ljava/lang/String;<br /> */<br />JNIEXPORT jstring JNICALL Java_com_example_hellojni_HelloJni_stringFromJNI<br />  (JNIEnv *, jobject);<br /><br />/*<br /> * Class:     com_example_hellojni_HelloJni<br /> * Method:    unimplementedStringFromJNI<br /> * Signature: ()Ljava/lang/String;<br /> */<br />JNIEXPORT jstring JNICALL Java_com_example_hellojni_HelloJni_unimplementedStringFromJNI<br />  (JNIEnv *, jobject);<br /><br />#ifdef __cplusplus<br />}<br />#endif<br />#endif<br /></pre><p style="line-height: 28px; margin: 0px 0px 10px; padding: 0px; color: #333333; font-family: 'Hiragino Sans GB W3', 'Hiragino Sans GB', Arial, Helvetica, simsun, u5b8bu4f53; font-size: 16px; background-color: #ffffff;">从中可以找到native 方法对应的C函数定义，Java_com_example_hellojni_HelloJni_stringFromJNI</p><p style="line-height: 28px; margin: 0px 0px 10px; padding: 0px; color: #333333; font-family: 'Hiragino Sans GB W3', 'Hiragino Sans GB', Arial, Helvetica, simsun, u5b8bu4f53; font-size: 16px; background-color: #ffffff;">5. 定义对应的C函数，如Hello-jni 中定义</p><pre title="" style="line-height: 28px; white-space: pre-wrap; color: #333333; font-size: 16px; background-color: #ffffff;">#include &lt;string.h&gt;<br />#include &lt;jni.h&gt;<br /><br />/* This is a trivial JNI example where we use a native method<br /> * to return a new VM String. See the corresponding Java source<br /> * file located at:<br /> *<br /> *   apps/samples/hello-jni/project/src/com/example/HelloJni/HelloJni.java<br /> */<br />jstring<br />Java_com_example_hellojni_HelloJni_stringFromJNI( JNIEnv* env,<br />                                                  jobject thiz )<br />{<br />    return (*env)-&gt;NewStringUTF(env, "Hello from JNI !");<br />}<br /><br /></pre><p style="line-height: 28px; margin: 0px 0px 10px; padding: 0px; color: #333333; font-family: 'Hiragino Sans GB W3', 'Hiragino Sans GB', Arial, Helvetica, simsun, u5b8bu4f53; font-size: 16px; background-color: #ffffff;">6. 下面就可以使用ndk-build编译C代码，编译成功后会在libs 目录下生成libhello-jni.so<br /><img src="http://www.cppblog.com/images/cppblog_com/xkjy3000/BBB.png" width="175" height="168" align="absMiddle" alt="" /><br /></p><p style="line-height: 28px; margin: 0px 0px 10px; padding: 0px; color: #333333; font-family: 'Hiragino Sans GB W3', 'Hiragino Sans GB', Arial, Helvetica, simsun, u5b8bu4f53; font-size: 16px; background-color: #ffffff;">7. 在Java代码中调入编译好的C动态库</p><pre title="" style="line-height: 28px; white-space: pre-wrap; color: #333333; font-size: 16px; background-color: #ffffff;">static {<br />&nbsp;   System.loadLibrary("hello-jni");  <br />} </pre><p style="line-height: 28px; margin: 0px 0px 10px; padding: 0px; color: #333333; font-family: 'Hiragino Sans GB W3', 'Hiragino Sans GB', Arial, Helvetica, simsun, u5b8bu4f53; font-size: 16px; background-color: #ffffff;">8. 编译运行，为了测试你的NDK例子的确成功运行，可以对Java_com_example_hellojni_HelloJni_stringFromJNI ,做点小改动 返回 &#8220;Hello world from JNI1 !。&nbsp;<span style="color: #0000ff;">注意要Clean Project</span>，否则Eclipse可能不会重编译。<br /><img src="http://www.cppblog.com/images/cppblog_com/xkjy3000/CCC.png" width="480" height="800" align="absMiddle" alt="" /><br /></p><img src ="http://www.cppblog.com/xkjy3000/aggbug/204410.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/xkjy3000/" target="_blank">虚空骄阳</a> 2013-11-24 12:55 <a href="http://www.cppblog.com/xkjy3000/archive/2013/11/24/204410.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Android NDK 开发教程二：概述</title><link>http://www.cppblog.com/xkjy3000/archive/2013/11/24/204407.html</link><dc:creator>虚空骄阳</dc:creator><author>虚空骄阳</author><pubDate>Sun, 24 Nov 2013 04:46:00 GMT</pubDate><guid>http://www.cppblog.com/xkjy3000/archive/2013/11/24/204407.html</guid><wfw:comment>http://www.cppblog.com/xkjy3000/comments/204407.html</wfw:comment><comments>http://www.cppblog.com/xkjy3000/archive/2013/11/24/204407.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/xkjy3000/comments/commentRss/204407.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/xkjy3000/services/trackbacks/204407.html</trackback:ping><description><![CDATA[<p style="line-height: 28px; margin: 0px 0px 10px; padding: 0px; color: #333333; font-family: 'Hiragino Sans GB W3', 'Hiragino Sans GB', Arial, Helvetica, simsun, u5b8bu4f53; font-size: 16px; background-color: #ffffff;">注意：在Windows上运行NDK需要有<a rel="nofollow" href="http://www.cygwin.com/" style="text-decoration: none; color: #556c88;">Cygwin</a>支持，个人建议使用Ubuntu为好 。</p><p style="line-height: 28px; margin: 0px 0px 10px; padding: 0px; color: #333333; font-family: 'Hiragino Sans GB W3', 'Hiragino Sans GB', Arial, Helvetica, simsun, u5b8bu4f53; font-size: 16px; background-color: #ffffff;"><strong>介绍：</strong></p><p style="line-height: 28px; margin: 0px 0px 10px; padding: 0px; color: #333333; font-family: 'Hiragino Sans GB W3', 'Hiragino Sans GB', Arial, Helvetica, simsun, u5b8bu4f53; font-size: 16px; background-color: #ffffff;">Android SDK是一个允许Android应用开发人员使用C或C++源文件编译并嵌入到本机源代码中的应用程序包的一组工 具。</p><p style="line-height: 28px; margin: 0px 0px 10px; padding: 0px; color: #333333; font-family: 'Hiragino Sans GB W3', 'Hiragino Sans GB', Arial, Helvetica, simsun, u5b8bu4f53; font-size: 16px; background-color: #ffffff;"><strong>重要说明：</strong></p><p style="line-height: 28px; margin: 0px 0px 10px; padding: 0px; color: #333333; font-family: 'Hiragino Sans GB W3', 'Hiragino Sans GB', Arial, Helvetica, simsun, u5b8bu4f53; font-size: 16px; background-color: #ffffff;">Android NDK只能用于android 1.5以上版本</p><p style="line-height: 28px; margin: 0px 0px 10px; padding: 0px; color: #333333; font-family: 'Hiragino Sans GB W3', 'Hiragino Sans GB', Arial, Helvetica, simsun, u5b8bu4f53; font-size: 16px; background-color: #ffffff;"><strong>1</strong><strong>．</strong><strong>&nbsp;Android NDK</strong><strong>的目的：</strong></p><p style="line-height: 28px; margin: 0px 0px 10px; padding: 0px; color: #333333; font-family: 'Hiragino Sans GB W3', 'Hiragino Sans GB', Arial, Helvetica, simsun, u5b8bu4f53; font-size: 16px; background-color: #ffffff;">Android虚拟机允许你的应用程序源代码通过JNI调用在本地实现的源代码，简单的说，这就意味着：</p><p style="line-height: 28px; margin: 0px 0px 10px; padding: 0px; color: #333333; font-family: 'Hiragino Sans GB W3', 'Hiragino Sans GB', Arial, Helvetica, simsun, u5b8bu4f53; font-size: 16px; background-color: #ffffff;">&#8212;-你的应用程序将声明一个或多个用&#8217;native&#8217;关键字的方法用来指明它们是通过本地代码实现的</p><p style="line-height: 28px; margin: 0px 0px 10px; padding: 0px; color: #333333; font-family: 'Hiragino Sans GB W3', 'Hiragino Sans GB', Arial, Helvetica, simsun, u5b8bu4f53; font-size: 16px; background-color: #ffffff;">例如：native byte[] loadFile(String filePath)</p><p style="line-height: 28px; margin: 0px 0px 10px; padding: 0px; color: #333333; font-family: 'Hiragino Sans GB W3', 'Hiragino Sans GB', Arial, Helvetica, simsun, u5b8bu4f53; font-size: 16px; background-color: #ffffff;">&#8212;-你必须提供包含实现这些方法的共享库（就是.so），将共享库打包到你的应用程序包apk中，这些库文件必须根据 标准的Unix约定来命名为 lib&lt;something&gt;.so，并且是需要包含一个标准的JNI的接口，例如</p><p style="line-height: 28px; margin: 0px 0px 10px; padding: 0px; color: #333333; font-family: 'Hiragino Sans GB W3', 'Hiragino Sans GB', Arial, Helvetica, simsun, u5b8bu4f53; font-size: 16px; background-color: #ffffff;">libFileLoader.so</p><p style="line-height: 28px; margin: 0px 0px 10px; padding: 0px; color: #333333; font-family: 'Hiragino Sans GB W3', 'Hiragino Sans GB', Arial, Helvetica, simsun, u5b8bu4f53; font-size: 16px; background-color: #ffffff;">&#8212;-你的应用程序必须明确的装载这些库文件(.so文件)，比如，在程序的开始装载它，只需要简单的添加几句源代码：</p><p style="line-height: 28px; margin: 0px 0px 10px; padding: 0px; color: #333333; font-family: 'Hiragino Sans GB W3', 'Hiragino Sans GB', Arial, Helvetica, simsun, u5b8bu4f53; font-size: 16px; background-color: #ffffff;">static {</p><p style="line-height: 28px; margin: 0px 0px 10px; padding: 0px; color: #333333; font-family: 'Hiragino Sans GB W3', 'Hiragino Sans GB', Arial, Helvetica, simsun, u5b8bu4f53; font-size: 16px; background-color: #ffffff;">System.loadLibrary(&#8220;FileLoader&#8221;);</p><p style="line-height: 28px; margin: 0px 0px 10px; padding: 0px; color: #333333; font-family: 'Hiragino Sans GB W3', 'Hiragino Sans GB', Arial, Helvetica, simsun, u5b8bu4f53; font-size: 16px; background-color: #ffffff;">}</p><p style="line-height: 28px; margin: 0px 0px 10px; padding: 0px; color: #333333; font-family: 'Hiragino Sans GB W3', 'Hiragino Sans GB', Arial, Helvetica, simsun, u5b8bu4f53; font-size: 16px; background-color: #ffffff;">注意：这里你不必再将前缀lib和后缀.so写入。</p><p style="line-height: 28px; margin: 0px 0px 10px; padding: 0px; color: #333333; font-family: 'Hiragino Sans GB W3', 'Hiragino Sans GB', Arial, Helvetica, simsun, u5b8bu4f53; font-size: 16px; background-color: #ffffff;">Android NDK对于Android SDK只是个组件，它可以帮你：</p><p style="line-height: 28px; margin: 0px 0px 10px; padding: 0px; color: #333333; font-family: 'Hiragino Sans GB W3', 'Hiragino Sans GB', Arial, Helvetica, simsun, u5b8bu4f53; font-size: 16px; background-color: #ffffff;">&#8212;-生成的JNI兼容的共享库可以在大于Android1.5平台的ARM CPU上运行</p><p style="line-height: 28px; margin: 0px 0px 10px; padding: 0px; color: #333333; font-family: 'Hiragino Sans GB W3', 'Hiragino Sans GB', Arial, Helvetica, simsun, u5b8bu4f53; font-size: 16px; background-color: #ffffff;">&#8212;-将生成的共享库拷贝到合适的程序工程路径的位置上，以保证它们自动的添加到你的apk包中（并且签名的）</p><p style="line-height: 28px; margin: 0px 0px 10px; padding: 0px; color: #333333; font-family: 'Hiragino Sans GB W3', 'Hiragino Sans GB', Arial, Helvetica, simsun, u5b8bu4f53; font-size: 16px; background-color: #ffffff;">&#8212;-在以后的版本中，我们将提供来帮助你的源代码通过远程gdb连接和尽可能多的源代码的信息。</p><p style="line-height: 28px; margin: 0px 0px 10px; padding: 0px; color: #333333; font-family: 'Hiragino Sans GB W3', 'Hiragino Sans GB', Arial, Helvetica, simsun, u5b8bu4f53; font-size: 16px; background-color: #ffffff;">而且，Android NDK还提供：</p><p style="line-height: 28px; margin: 0px 0px 10px; padding: 0px; color: #333333; font-family: 'Hiragino Sans GB W3', 'Hiragino Sans GB', Arial, Helvetica, simsun, u5b8bu4f53; font-size: 16px; background-color: #ffffff;">&#8212;-一组交叉编译链（编译器、链接器等）来生成可以在Linux，OS X和Windows(用Cygwin)运行的二进制文件</p><p style="line-height: 28px; margin: 0px 0px 10px; padding: 0px; color: #333333; font-family: 'Hiragino Sans GB W3', 'Hiragino Sans GB', Arial, Helvetica, simsun, u5b8bu4f53; font-size: 16px; background-color: #ffffff;">&#8212;-一组与由Android平台提供的稳定的本地API列表的头文件</p><p style="line-height: 28px; margin: 0px 0px 10px; padding: 0px; color: #333333; font-family: 'Hiragino Sans GB W3', 'Hiragino Sans GB', Arial, Helvetica, simsun, u5b8bu4f53; font-size: 16px; background-color: #ffffff;">它们在docs/STABLE-APIS.html中有说明</p><p style="line-height: 28px; margin: 0px 0px 10px; padding: 0px; color: #333333; font-family: 'Hiragino Sans GB W3', 'Hiragino Sans GB', Arial, Helvetica, simsun, u5b8bu4f53; font-size: 16px; background-color: #ffffff;">重要提示：</p><p style="line-height: 28px; margin: 0px 0px 10px; padding: 0px; color: #333333; font-family: 'Hiragino Sans GB W3', 'Hiragino Sans GB', Arial, Helvetica, simsun, u5b8bu4f53; font-size: 16px; background-color: #ffffff;">记住，在以后的更新和发布平台中，Android系统镜像中的大多数本地系统库并不是一成不变的，而是可以彻底改变， 甚至删除的</p><p style="line-height: 28px; margin: 0px 0px 10px; padding: 0px; color: #333333; font-family: 'Hiragino Sans GB W3', 'Hiragino Sans GB', Arial, Helvetica, simsun, u5b8bu4f53; font-size: 16px; background-color: #ffffff;">&#8212;-一个编译系统（build system）可以允许开发者写一个非常短的编译文件（build files）去描述哪个源代码需要编 译，并且怎样编译。编译系统可以解决所有的toolchain/platform/CPU/ABI细节的问题。并且，较晚的NDK版 本中还添加了更多的可以不用改变开发者的编译文件的情况下的toolchains，platforms，系统接口</p><p style="line-height: 28px; margin: 0px 0px 10px; padding: 0px; color: #333333; font-family: 'Hiragino Sans GB W3', 'Hiragino Sans GB', Arial, Helvetica, simsun, u5b8bu4f53; font-size: 16px; background-color: #ffffff;"><strong>2</strong><strong>．</strong><strong>Android NDK</strong><strong>的缺点</strong></p><p style="line-height: 28px; margin: 0px 0px 10px; padding: 0px; color: #333333; font-family: 'Hiragino Sans GB W3', 'Hiragino Sans GB', Arial, Helvetica, simsun, u5b8bu4f53; font-size: 16px; background-color: #ffffff;">NDK并不是一个可以编写通用的源代码并且可以在Android设备上运行的方法，你的应用程序还是需要使用JAVA程序，适当的处理系统事件来避免&#8220;应用程序没有反应&#8221;的对话框或者处理Android应用程序的生命周期</p><p style="line-height: 28px; margin: 0px 0px 10px; padding: 0px; color: #333333; font-family: 'Hiragino Sans GB W3', 'Hiragino Sans GB', Arial, Helvetica, simsun, u5b8bu4f53; font-size: 16px; background-color: #ffffff;">注意：可以适当的在源代码中写一个复杂的应用程序，用于启动/停止一个小型的&#8220;应用程序包&#8221;</p><p style="line-height: 28px; margin: 0px 0px 10px; padding: 0px; color: #333333; font-family: 'Hiragino Sans GB W3', 'Hiragino Sans GB', Arial, Helvetica, simsun, u5b8bu4f53; font-size: 16px; background-color: #ffffff;">强烈建议很好地理解的 JNI，因为许多操作在这种环境要求的开发人员，都采取具体的行动，不一定在常见典型的本机代码。这些措施包括：</p><p style="line-height: 28px; margin: 0px 0px 10px; padding: 0px; color: #333333; font-family: 'Hiragino Sans GB W3', 'Hiragino Sans GB', Arial, Helvetica, simsun, u5b8bu4f53; font-size: 16px; background-color: #ffffff;">&#8212;-不能通过指针直接访问VM的对象。比如：你不能安全的得到一个指向String对象的16位char数组的循环遍历</p><p style="line-height: 28px; margin: 0px 0px 10px; padding: 0px; color: #333333; font-family: 'Hiragino Sans GB W3', 'Hiragino Sans GB', Arial, Helvetica, simsun, u5b8bu4f53; font-size: 16px; background-color: #ffffff;">&#8212;-需要显示引用管理本机代码时候要保持处理JNI调用之间的VM对象</p><p style="line-height: 28px; margin: 0px 0px 10px; padding: 0px; color: #333333; font-family: 'Hiragino Sans GB W3', 'Hiragino Sans GB', Arial, Helvetica, simsun, u5b8bu4f53; font-size: 16px; background-color: #ffffff;">NDK在Android平台仅仅提供了有限的本地API和库文件的支持的系统头文件，然而一个标准的Android系统镜像包括许多本地共享库，这些都应该被考虑在更新和发行版本的可以彻底改变的实现细节</p><p style="line-height: 28px; margin: 0px 0px 10px; padding: 0px; color: #333333; font-family: 'Hiragino Sans GB W3', 'Hiragino Sans GB', Arial, Helvetica, simsun, u5b8bu4f53; font-size: 16px; background-color: #ffffff;">如果Android系统库没有明确的被NDK明确的支持，然后应用程序不应该依赖于它提供的，或者打破了将来在各种设备上的无线系统更新</p><p style="line-height: 28px; margin: 0px 0px 10px; padding: 0px; color: #333333; font-family: 'Hiragino Sans GB W3', 'Hiragino Sans GB', Arial, Helvetica, simsun, u5b8bu4f53; font-size: 16px; background-color: #ffffff;">选定的系统库将逐渐被添加到稳定的NDK API中</p><p style="line-height: 28px; margin: 0px 0px 10px; padding: 0px; color: #333333; font-family: 'Hiragino Sans GB W3', 'Hiragino Sans GB', Arial, Helvetica, simsun, u5b8bu4f53; font-size: 16px; background-color: #ffffff;"><strong>3</strong><strong>．</strong><strong>NDK</strong><strong>开发实践</strong></p><p style="line-height: 28px; margin: 0px 0px 10px; padding: 0px; color: #333333; font-family: 'Hiragino Sans GB W3', 'Hiragino Sans GB', Arial, Helvetica, simsun, u5b8bu4f53; font-size: 16px; background-color: #ffffff;">下面将给出一个怎样用Android NDK开发本地代码的粗略的概述</p><p style="line-height: 28px; margin: 0px 0px 10px; padding: 0px; color: #333333; font-family: 'Hiragino Sans GB W3', 'Hiragino Sans GB', Arial, Helvetica, simsun, u5b8bu4f53; font-size: 16px; background-color: #ffffff;">（1） 把本地代码放在$PROJECT/jni/&#8230;下，比如将hello.c放到apps/hello/jni/目录下</p><p style="line-height: 28px; margin: 0px 0px 10px; padding: 0px; color: #333333; font-family: 'Hiragino Sans GB W3', 'Hiragino Sans GB', Arial, Helvetica, simsun, u5b8bu4f53; font-size: 16px; background-color: #ffffff;">（2） 在你的NDK编译系统中在$PROJECT/jni/Android.mk来描述你的源代码</p><p style="line-height: 28px; margin: 0px 0px 10px; padding: 0px; color: #333333; font-family: 'Hiragino Sans GB W3', 'Hiragino Sans GB', Arial, Helvetica, simsun, u5b8bu4f53; font-size: 16px; background-color: #ffffff;">（3） 可选：在$PROJECT/jni/Application.mk到你的编译系统中来详细描述你的项目，尽管你开始的话不一定需要它， 但是它允许你使用更多的CPU或者覆盖编译器/链接器的标记（看docs/APPLICATION-MK.html了解更多细节）</p><p style="line-height: 28px; margin: 0px 0px 10px; padding: 0px; color: #333333; font-family: 'Hiragino Sans GB W3', 'Hiragino Sans GB', Arial, Helvetica, simsun, u5b8bu4f53; font-size: 16px; background-color: #ffffff;">（4） 从你的项目的目录开始通过运行&#8221;$NDK/ndk-build&#8221;来编译你的代码，或者从子目录开始</p><p style="line-height: 28px; margin: 0px 0px 10px; padding: 0px; color: #333333; font-family: 'Hiragino Sans GB W3', 'Hiragino Sans GB', Arial, Helvetica, simsun, u5b8bu4f53; font-size: 16px; background-color: #ffffff;">（5） 最后一步可以copy，万一成功，剥离共享库的应用层序需要你的应用程序的项目根目录。然后你通过通常的方法来 生成最终的apk</p><p style="line-height: 28px; margin: 0px 0px 10px; padding: 0px; color: #333333; font-family: 'Hiragino Sans GB W3', 'Hiragino Sans GB', Arial, Helvetica, simsun, u5b8bu4f53; font-size: 16px; background-color: #ffffff;">现在，开始一些更 的细节</p><p style="line-height: 28px; margin: 0px 0px 10px; padding: 0px; color: #333333; font-family: 'Hiragino Sans GB W3', 'Hiragino Sans GB', Arial, Helvetica, simsun, u5b8bu4f53; font-size: 16px; background-color: #ffffff;">&#9312; 配置N DK</p><p style="line-height: 28px; margin: 0px 0px 10px; padding: 0px; color: #333333; font-family: 'Hiragino Sans GB W3', 'Hiragino Sans GB', Arial, Helvetica, simsun, u5b8bu4f53; font-size: 16px; background-color: #ffffff;">以前的发行版本需要你运行&#8220;build/host-setup.sh&#8221;脚本来配置你的NDK。从release 4(NDK r)以后就完全去除了这一步</p><p style="line-height: 28px; margin: 0px 0px 10px; padding: 0px; color: #333333; font-family: 'Hiragino Sans GB W3', 'Hiragino Sans GB', Arial, Helvetica, simsun, u5b8bu4f53; font-size: 16px; background-color: #ffffff;">&#9313; 放置C/C++代码</p><p style="line-height: 28px; margin: 0px 0px 10px; padding: 0px; color: #333333; font-family: 'Hiragino Sans GB W3', 'Hiragino Sans GB', Arial, Helvetica, simsun, u5b8bu4f53; font-size: 16px; background-color: #ffffff;">假如我们创建的是test目录，创建的代码hello.c</p><p style="line-height: 28px; margin: 0px 0px 10px; padding: 0px; color: #333333; font-family: 'Hiragino Sans GB W3', 'Hiragino Sans GB', Arial, Helvetica, simsun, u5b8bu4f53; font-size: 16px; background-color: #ffffff;">把hello.c放到test/jni目录下</p><p style="line-height: 28px; margin: 0px 0px 10px; padding: 0px; color: #333333; font-family: 'Hiragino Sans GB W3', 'Hiragino Sans GB', Arial, Helvetica, simsun, u5b8bu4f53; font-size: 16px; background-color: #ffffff;">这个项目的位置相当于你的Android应用程序项目的路径</p><p style="line-height: 28px; margin: 0px 0px 10px; padding: 0px; color: #333333; font-family: 'Hiragino Sans GB W3', 'Hiragino Sans GB', Arial, Helvetica, simsun, u5b8bu4f53; font-size: 16px; background-color: #ffffff;">这样你就很轻松的组织起来了你想要的jni的目录，这里项目目录的名字和结构不会影响到最终生成的apk，所以 你不必用类似于com.&lt;mycompany&gt;.&lt;myproject&gt;作为应用程序包名</p><p style="line-height: 28px; margin: 0px 0px 10px; padding: 0px; color: #333333; font-family: 'Hiragino Sans GB W3', 'Hiragino Sans GB', Arial, Helvetica, simsun, u5b8bu4f53; font-size: 16px; background-color: #ffffff;">注意，NDK是支持C和C++的，NDK支持的C++文件扩展名是&#8217;.cpp&#8217;，但是其他的扩展名也是可以被处理的 &nbsp;&nbsp;&nbsp; （看docs/ANDROID-MK.html了解更多）</p><p style="line-height: 28px; margin: 0px 0px 10px; padding: 0px; color: #333333; font-family: 'Hiragino Sans GB W3', 'Hiragino Sans GB', Arial, Helvetica, simsun, u5b8bu4f53; font-size: 16px; background-color: #ffffff;">它可以通过调整你的Android.mk文件来将源代码放在不同的位置</p><p style="line-height: 28px; margin: 0px 0px 10px; padding: 0px; color: #333333; font-family: 'Hiragino Sans GB W3', 'Hiragino Sans GB', Arial, Helvetica, simsun, u5b8bu4f53; font-size: 16px; background-color: #ffffff;">&#9314; 创建一个Android.mk编译脚本</p><p style="line-height: 28px; margin: 0px 0px 10px; padding: 0px; color: #333333; font-family: 'Hiragino Sans GB W3', 'Hiragino Sans GB', Arial, Helvetica, simsun, u5b8bu4f53; font-size: 16px; background-color: #ffffff;">Android.mk文件是一个小型的编译脚本，你可以在NDK编译系统中用它来描述你的源代码。更详细的描述在docs/ANDROID-MK.html中</p><p style="line-height: 28px; margin: 0px 0px 10px; padding: 0px; color: #333333; font-family: 'Hiragino Sans GB W3', 'Hiragino Sans GB', Arial, Helvetica, simsun, u5b8bu4f53; font-size: 16px; background-color: #ffffff;">总而言之，NDK将你的源代码聚合到模块(modules)中，每个模块可以执行下列之一</p><p style="line-height: 28px; margin: 0px 0px 10px; padding: 0px; color: #333333; font-family: 'Hiragino Sans GB W3', 'Hiragino Sans GB', Arial, Helvetica, simsun, u5b8bu4f53; font-size: 16px; background-color: #ffffff;">&#8212;-一个静态库(lib&lt;project&gt;.a)</p><p style="line-height: 28px; margin: 0px 0px 10px; padding: 0px; color: #333333; font-family: 'Hiragino Sans GB W3', 'Hiragino Sans GB', Arial, Helvetica, simsun, u5b8bu4f53; font-size: 16px; background-color: #ffffff;">&#8212;-一个动态库(lib&lt;project&gt;.so)</p><p style="line-height: 28px; margin: 0px 0px 10px; padding: 0px; color: #333333; font-family: 'Hiragino Sans GB W3', 'Hiragino Sans GB', Arial, Helvetica, simsun, u5b8bu4f53; font-size: 16px; background-color: #ffffff;">你可以在Android.mk中定义多个模块，或者你可以编写多个Android.mk文件，每一个定义一个单独的模块</p><p style="line-height: 28px; margin: 0px 0px 10px; padding: 0px; color: #333333; font-family: 'Hiragino Sans GB W3', 'Hiragino Sans GB', Arial, Helvetica, simsun, u5b8bu4f53; font-size: 16px; background-color: #ffffff;">注意，单独的Android.mk也行被编译系统多次解析，以确定哪些变量没有被定义。</p><p style="line-height: 28px; margin: 0px 0px 10px; padding: 0px; color: #333333; font-family: 'Hiragino Sans GB W3', 'Hiragino Sans GB', Arial, Helvetica, simsun, u5b8bu4f53; font-size: 16px; background-color: #ffffff;">默认地，NDK会通过如下的编译脚本去寻找</p><p style="line-height: 28px; margin: 0px 0px 10px; padding: 0px; color: #333333; font-family: 'Hiragino Sans GB W3', 'Hiragino Sans GB', Arial, Helvetica, simsun, u5b8bu4f53; font-size: 16px; background-color: #ffffff;">test/jni/Android.mk（存放位置）</p><p style="line-height: 28px; margin: 0px 0px 10px; padding: 0px; color: #333333; font-family: 'Hiragino Sans GB W3', 'Hiragino Sans GB', Arial, Helvetica, simsun, u5b8bu4f53; font-size: 16px; background-color: #ffffff;">如果你想定义Android.mk到子目录中，你需要在最高层的Android.mk中明确的包含它们，下面是一个帮助的方法可以实现这个功能。</p><p style="line-height: 28px; margin: 0px 0px 10px; padding: 0px; color: #333333; font-family: 'Hiragino Sans GB W3', 'Hiragino Sans GB', Arial, Helvetica, simsun, u5b8bu4f53; font-size: 16px; background-color: #ffffff;">include $(call all-subdir-makefiles)</p><p style="line-height: 28px; margin: 0px 0px 10px; padding: 0px; color: #333333; font-family: 'Hiragino Sans GB W3', 'Hiragino Sans GB', Arial, Helvetica, simsun, u5b8bu4f53; font-size: 16px; background-color: #ffffff;">它会将所有的在子目录中的Android.mk文件加入到当前编译文件的路径中</p><p style="line-height: 28px; margin: 0px 0px 10px; padding: 0px; color: #333333; font-family: 'Hiragino Sans GB W3', 'Hiragino Sans GB', Arial, Helvetica, simsun, u5b8bu4f53; font-size: 16px; background-color: #ffffff;">&#9315; 写一个Application.mk编译文件（可选）</p><p style="line-height: 28px; margin: 0px 0px 10px; padding: 0px; color: #333333; font-family: 'Hiragino Sans GB W3', 'Hiragino Sans GB', Arial, Helvetica, simsun, u5b8bu4f53; font-size: 16px; background-color: #ffffff;">在你的编译系统中有一个Android.mk文件描述模块的同时，Application.mk文件藐视你的应用程序本身。请看docs/APPLICATION-MK.html文档来理解这个文件允许我们做什么。这包括</p><p style="line-height: 28px; margin: 0px 0px 10px; padding: 0px; color: #333333; font-family: 'Hiragino Sans GB W3', 'Hiragino Sans GB', Arial, Helvetica, simsun, u5b8bu4f53; font-size: 16px; background-color: #ffffff;">&#8212;-你的应用程序需要模块的准确清单</p><p style="line-height: 28px; margin: 0px 0px 10px; padding: 0px; color: #333333; font-family: 'Hiragino Sans GB W3', 'Hiragino Sans GB', Arial, Helvetica, simsun, u5b8bu4f53; font-size: 16px; background-color: #ffffff;">&#8212;-CPU架构生成机器代码</p><p style="line-height: 28px; margin: 0px 0px 10px; padding: 0px; color: #333333; font-family: 'Hiragino Sans GB W3', 'Hiragino Sans GB', Arial, Helvetica, simsun, u5b8bu4f53; font-size: 16px; background-color: #ffffff;">&#8212;-可选信息，你是否需要一个release或者debug build，特殊的C/C++编译器标志和其他适用于所有模块的build</p><p style="line-height: 28px; margin: 0px 0px 10px; padding: 0px; color: #333333; font-family: 'Hiragino Sans GB W3', 'Hiragino Sans GB', Arial, Helvetica, simsun, u5b8bu4f53; font-size: 16px; background-color: #ffffff;">这个文件是可选文件：默认地，NDK会提供一个对于所有的在你的Android.mk（所有的makefiles都在里面）中的所有模块的简单编译并且指定默认的CPU ABI</p><p style="line-height: 28px; margin: 0px 0px 10px; padding: 0px; color: #333333; font-family: 'Hiragino Sans GB W3', 'Hiragino Sans GB', Arial, Helvetica, simsun, u5b8bu4f53; font-size: 16px; background-color: #ffffff;">使用Application.mk有两种方法：</p><p style="line-height: 28px; margin: 0px 0px 10px; padding: 0px; color: #333333; font-family: 'Hiragino Sans GB W3', 'Hiragino Sans GB', Arial, Helvetica, simsun, u5b8bu4f53; font-size: 16px; background-color: #ffffff;">&#8212;-把它放到 test/jni/Application.mk，它就会自动的被&#8217;ndk-build&#8217;脚本找出来</p><p style="line-height: 28px; margin: 0px 0px 10px; padding: 0px; color: #333333; font-family: 'Hiragino Sans GB W3', 'Hiragino Sans GB', Arial, Helvetica, simsun, u5b8bu4f53; font-size: 16px; background-color: #ffffff;">&#8212;-把它放在NDK/&lt;name&gt;/Application.mk，也就是NDK安装的路径下，然后从NDK目录下执行&#8221;make APP=&lt;name&gt;&#8221;</p><p style="line-height: 28px; margin: 0px 0px 10px; padding: 0px; color: #333333; font-family: 'Hiragino Sans GB W3', 'Hiragino Sans GB', Arial, Helvetica, simsun, u5b8bu4f53; font-size: 16px; background-color: #ffffff;">这个方法是Android NDK r4以前的。现在仍然兼容。但是我们强烈建议你使用第一种方法，因为它更简单并且不用修改NDK安装树的目录。</p><p style="line-height: 28px; margin: 0px 0px 10px; padding: 0px; color: #333333; font-family: 'Hiragino Sans GB W3', 'Hiragino Sans GB', Arial, Helvetica, simsun, u5b8bu4f53; font-size: 16px; background-color: #ffffff;">再次看看docs/APPLICATION-MK.html对于它的完整说明</p><p style="line-height: 28px; margin: 0px 0px 10px; padding: 0px; color: #333333; font-family: 'Hiragino Sans GB W3', 'Hiragino Sans GB', Arial, Helvetica, simsun, u5b8bu4f53; font-size: 16px; background-color: #ffffff;">&#9316; 调用NDK编译系统</p><p style="line-height: 28px; margin: 0px 0px 10px; padding: 0px; color: #333333; font-family: 'Hiragino Sans GB W3', 'Hiragino Sans GB', Arial, Helvetica, simsun, u5b8bu4f53; font-size: 16px; background-color: #ffffff;">用NDK编译成机器码的最好方法是使用&#8221;ndk-build&#8221;脚本，你还可以使用第二个，这取决于你早起常见的&#8221;$NDK/apps&#8221;子目录</p><p style="line-height: 28px; margin: 0px 0px 10px; padding: 0px; color: #333333; font-family: 'Hiragino Sans GB W3', 'Hiragino Sans GB', Arial, Helvetica, simsun, u5b8bu4f53; font-size: 16px; background-color: #ffffff;">在两种情况下，成功构建将copy应用程序所需的最终的已经剥离的二进制模块（即共享库）到应用程序的项目路径中（注意，未剥离的版本主要是用于调试目的，无需拷贝未剥离的二进制文件到设备中）</p><p style="line-height: 28px; margin: 0px 0px 10px; padding: 0px; color: #333333; font-family: 'Hiragino Sans GB W3', 'Hiragino Sans GB', Arial, Helvetica, simsun, u5b8bu4f53; font-size: 16px; background-color: #ffffff;">[1]：使用&#8217;ndk-build&#8217;命令</p><p style="line-height: 28px; margin: 0px 0px 10px; padding: 0px; color: #333333; font-family: 'Hiragino Sans GB W3', 'Hiragino Sans GB', Arial, Helvetica, simsun, u5b8bu4f53; font-size: 16px; background-color: #ffffff;">&#8216;ndk-build&#8217;脚本位于NDK安装目录最顶层，可以直接被应用程序项目目录（你的AndroidManifest.xml文件所在位置）或者其他任何子目录</p><p style="line-height: 28px; margin: 0px 0px 10px; padding: 0px; color: #333333; font-family: 'Hiragino Sans GB W3', 'Hiragino Sans GB', Arial, Helvetica, simsun, u5b8bu4f53; font-size: 16px; background-color: #ffffff;">$ cd $PROJECT</p><p style="line-height: 28px; margin: 0px 0px 10px; padding: 0px; color: #333333; font-family: 'Hiragino Sans GB W3', 'Hiragino Sans GB', Arial, Helvetica, simsun, u5b8bu4f53; font-size: 16px; background-color: #ffffff;">$ $NDK/ndk-build(注意是$NDK/ndkbuild，这是个命令)<br />将启动NDK的build脚本，它会自动探测您开发的系统和应用程序项目文件，以确定build设么</p><p style="line-height: 28px; margin: 0px 0px 10px; padding: 0px; color: #333333; font-family: 'Hiragino Sans GB W3', 'Hiragino Sans GB', Arial, Helvetica, simsun, u5b8bu4f53; font-size: 16px; background-color: #ffffff;">例如：</p><p style="line-height: 28px; margin: 0px 0px 10px; padding: 0px; color: #333333; font-family: 'Hiragino Sans GB W3', 'Hiragino Sans GB', Arial, Helvetica, simsun, u5b8bu4f53; font-size: 16px; background-color: #ffffff;">$ndk-build</p><p style="line-height: 28px; margin: 0px 0px 10px; padding: 0px; color: #333333; font-family: 'Hiragino Sans GB W3', 'Hiragino Sans GB', Arial, Helvetica, simsun, u5b8bu4f53; font-size: 16px; background-color: #ffffff;">$ndk-build clean &#224;清理生成的二进制文件</p><p style="line-height: 28px; margin: 0px 0px 10px; padding: 0px; color: #333333; font-family: 'Hiragino Sans GB W3', 'Hiragino Sans GB', Arial, Helvetica, simsun, u5b8bu4f53; font-size: 16px; background-color: #ffffff;">$ndk-build &#8211;B V=1 &#224;强制完全重新build，显示命令</p><p style="line-height: 28px; margin: 0px 0px 10px; padding: 0px; color: #333333; font-family: 'Hiragino Sans GB W3', 'Hiragino Sans GB', Arial, Helvetica, simsun, u5b8bu4f53; font-size: 16px; background-color: #ffffff;">默认的，它期望的是可选文件$PROJECT/jni/Application.mk和必须的文件$PROJECT/jni/Android.mk</p><p style="line-height: 28px; margin: 0px 0px 10px; padding: 0px; color: #333333; font-family: 'Hiragino Sans GB W3', 'Hiragino Sans GB', Arial, Helvetica, simsun, u5b8bu4f53; font-size: 16px; background-color: #ffffff;">成功的话，它讲话就复制生成的二进制模块（即共享库.so文件）到你的项目树中的适当位置。您可以在以后重新build完整的Android应用程序包或者通过&#8220;ant&#8221;命令，或者ADT插件。</p><p style="line-height: 28px; margin: 0px 0px 10px; padding: 0px; color: #333333; font-family: 'Hiragino Sans GB W3', 'Hiragino Sans GB', Arial, Helvetica, simsun, u5b8bu4f53; font-size: 16px; background-color: #ffffff;">可以看docs/NDK-BUILD.html来了解更多的信息</p><p style="line-height: 28px; margin: 0px 0px 10px; padding: 0px; color: #333333; font-family: 'Hiragino Sans GB W3', 'Hiragino Sans GB', Arial, Helvetica, simsun, u5b8bu4f53; font-size: 16px; background-color: #ffffff;">[2]：使用$NDK/apps/&lt;name&gt;/Application.mk</p><p style="line-height: 28px; margin: 0px 0px 10px; padding: 0px; color: #333333; font-family: 'Hiragino Sans GB W3', 'Hiragino Sans GB', Arial, Helvetica, simsun, u5b8bu4f53; font-size: 16px; background-color: #ffffff;">这种build方法是在Android NDK r4版本之前的，不过依然兼容现在的。我们强烈建议您尽可能的使用&#8217;ndk-build&#8217;，因为我们可能会删除在以后的NDK发行版本中的支持</p><p style="line-height: 28px; margin: 0px 0px 10px; padding: 0px; color: #333333; font-family: 'Hiragino Sans GB W3', 'Hiragino Sans GB', Arial, Helvetica, simsun, u5b8bu4f53; font-size: 16px; background-color: #ffffff;">&#9312; 创建一个子目录为$NDK/apps/&lt;name&gt;/</p><p style="line-height: 28px; margin: 0px 0px 10px; padding: 0px; color: #333333; font-family: 'Hiragino Sans GB W3', 'Hiragino Sans GB', Arial, Helvetica, simsun, u5b8bu4f53; font-size: 16px; background-color: #ffffff;">&#9313; 在$NDK/apps/&lt;name&gt;/目录下写一个Application.mk文件，然后需要定义一个APP_PROJECT_PATH来 执行你的应用程序项目的目录。</p><p style="line-height: 28px; margin: 0px 0px 10px; padding: 0px; color: #333333; font-family: 'Hiragino Sans GB W3', 'Hiragino Sans GB', Arial, Helvetica, simsun, u5b8bu4f53; font-size: 16px; background-color: #ffffff;">&#9314; 进入到NDK安装目录，然后再输入如下的命令</p><p style="line-height: 28px; margin: 0px 0px 10px; padding: 0px; color: #333333; font-family: 'Hiragino Sans GB W3', 'Hiragino Sans GB', Arial, Helvetica, simsun, u5b8bu4f53; font-size: 16px; background-color: #ffffff;">$cd $NDK<br />注意：输入cd $NDK后，会自动跳到你设置的ndk的目录中</p><p style="line-height: 28px; margin: 0px 0px 10px; padding: 0px; color: #333333; font-family: 'Hiragino Sans GB W3', 'Hiragino Sans GB', Arial, Helvetica, simsun, u5b8bu4f53; font-size: 16px; background-color: #ffffff;">$make APP=&lt;name&gt;</p><p style="line-height: 28px; margin: 0px 0px 10px; padding: 0px; color: #333333; font-family: 'Hiragino Sans GB W3', 'Hiragino Sans GB', Arial, Helvetica, simsun, u5b8bu4f53; font-size: 16px; background-color: #ffffff;">或</p><p style="line-height: 28px; margin: 0px 0px 10px; padding: 0px; color: #333333; font-family: 'Hiragino Sans GB W3', 'Hiragino Sans GB', Arial, Helvetica, simsun, u5b8bu4f53; font-size: 16px; background-color: #ffffff;">$make APP=&lt;name&gt; -B 表示重新编译</p><p style="line-height: 28px; margin: 0px 0px 10px; padding: 0px; color: #333333; font-family: 'Hiragino Sans GB W3', 'Hiragino Sans GB', Arial, Helvetica, simsun, u5b8bu4f53; font-size: 16px; background-color: #ffffff;">结果跟第一种方法一样，除了中间文件被放置到了$NDK/out/apps/&lt;name&gt;/</p><p style="line-height: 28px; margin: 0px 0px 10px; padding: 0px; color: #333333; font-family: 'Hiragino Sans GB W3', 'Hiragino Sans GB', Arial, Helvetica, simsun, u5b8bu4f53; font-size: 16px; background-color: #ffffff;"><strong>4</strong><strong>．从新</strong><strong>build</strong><strong>你的应用程序包</strong></p><p style="line-height: 28px; margin: 0px 0px 10px; padding: 0px; color: #333333; font-family: 'Hiragino Sans GB W3', 'Hiragino Sans GB', Arial, Helvetica, simsun, u5b8bu4f53; font-size: 16px; background-color: #ffffff;">在NDK生成的二进制文件后，你需要使用一般的方法来重新build你的Android应用程序包文件(apk)，或者用&#8220;ant&#8221;命令或者ADT插件</p><p style="line-height: 28px; margin: 0px 0px 10px; padding: 0px; color: #333333; font-family: 'Hiragino Sans GB W3', 'Hiragino Sans GB', Arial, Helvetica, simsun, u5b8bu4f53; font-size: 16px; background-color: #ffffff;">有关详细信息，请参阅Android SDK的文档，新的.apk会嵌入到您的共享库中，他们将自动提取安装时由系统安装的软件包到你的Android设备上</p><p style="line-height: 28px; margin: 0px 0px 10px; padding: 0px; color: #333333; font-family: 'Hiragino Sans GB W3', 'Hiragino Sans GB', Arial, Helvetica, simsun, u5b8bu4f53; font-size: 16px; background-color: #ffffff;"><strong>5</strong><strong>．</strong><strong>&nbsp;</strong><strong>调试支持</strong></p><p style="line-height: 28px; margin: 0px 0px 10px; padding: 0px; color: #333333; font-family: 'Hiragino Sans GB W3', 'Hiragino Sans GB', Arial, Helvetica, simsun, u5b8bu4f53; font-size: 16px; background-color: #ffffff;">NDK提供了一个服务脚本，名字叫&#8221;ndk-gdb&#8221;，很容易推出一个应用程序的本地调试会话。</p><p style="line-height: 28px; margin: 0px 0px 10px; padding: 0px; color: #333333; font-family: 'Hiragino Sans GB W3', 'Hiragino Sans GB', Arial, Helvetica, simsun, u5b8bu4f53; font-size: 16px; background-color: #ffffff;">本机调试仅仅能运行在Android 2.2或者更高版本，并且不需要root权限或者特权访问，所以可以随意调试你的应用程序。</p><p style="line-height: 28px; margin: 0px 0px 10px; padding: 0px; color: #333333; font-family: 'Hiragino Sans GB W3', 'Hiragino Sans GB', Arial, Helvetica, simsun, u5b8bu4f53; font-size: 16px; background-color: #ffffff;">有关详细信息，请阅读DOCS / NDK- GDB.html。总括而言，本机调试<br />遵循这个简单的计划：<br />（1）确保您的应用程序调试（如设置机器人：调试&#8220;真&#8221;，在您的AndroidManifest.xml）</p><p style="line-height: 28px; margin: 0px 0px 10px; padding: 0px; color: #333333; font-family: 'Hiragino Sans GB W3', 'Hiragino Sans GB', Arial, Helvetica, simsun, u5b8bu4f53; font-size: 16px; background-color: #ffffff;">（2） &#8220;NDK构建&#8221;构建您的应用程序，然后安装在您的 设备/模拟器</p><p style="line-height: 28px; margin: 0px 0px 10px; padding: 0px; color: #333333; font-family: 'Hiragino Sans GB W3', 'Hiragino Sans GB', Arial, Helvetica, simsun, u5b8bu4f53; font-size: 16px; background-color: #ffffff;">（3）启动应用程序。</p><p style="line-height: 28px; margin: 0px 0px 10px; padding: 0px; color: #333333; font-family: 'Hiragino Sans GB W3', 'Hiragino Sans GB', Arial, Helvetica, simsun, u5b8bu4f53; font-size: 16px; background-color: #ffffff;">（4）运行&#8220;ndk-gdb&#8221;从你的应用程序项目目录。</p><p style="line-height: 28px; margin: 0px 0px 10px; padding: 0px; color: #333333; font-family: 'Hiragino Sans GB W3', 'Hiragino Sans GB', Arial, Helvetica, simsun, u5b8bu4f53; font-size: 16px; background-color: #ffffff;">你会得到一个gdb提示符。一个有用的列表，请参阅GDB用户手册命令。</p><img src ="http://www.cppblog.com/xkjy3000/aggbug/204407.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/xkjy3000/" target="_blank">虚空骄阳</a> 2013-11-24 12:46 <a href="http://www.cppblog.com/xkjy3000/archive/2013/11/24/204407.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Android NDK 开发教程一：安装NDK</title><link>http://www.cppblog.com/xkjy3000/archive/2013/11/24/204406.html</link><dc:creator>虚空骄阳</dc:creator><author>虚空骄阳</author><pubDate>Sun, 24 Nov 2013 04:45:00 GMT</pubDate><guid>http://www.cppblog.com/xkjy3000/archive/2013/11/24/204406.html</guid><wfw:comment>http://www.cppblog.com/xkjy3000/comments/204406.html</wfw:comment><comments>http://www.cppblog.com/xkjy3000/archive/2013/11/24/204406.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/xkjy3000/comments/commentRss/204406.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/xkjy3000/services/trackbacks/204406.html</trackback:ping><description><![CDATA[<span style="color: #333333; font-family: 'Hiragino Sans GB W3', 'Hiragino Sans GB', Arial, Helvetica, simsun, u5b8bu4f53; font-size: 16px; line-height: 28px; background-color: #ffffff;">Android OS 的基本框架为Linux-Java ，在介绍Android开发时用到的Android结构图：<br /></span><img src="http://www.cppblog.com/images/cppblog_com/xkjy3000/1.jpg" width="713" height="512" align="absMiddle" alt="" /><br /><p style="line-height: 28px; margin: 0px 0px 10px; padding: 0px; color: #333333; font-family: 'Hiragino Sans GB W3', 'Hiragino Sans GB', Arial, Helvetica, simsun, u5b8bu4f53; font-size: 16px; background-color: #ffffff;">android 体系底层为Linux内核，之上提供一些C/C++函数库，因此Android 应用开发也可以使用C /C++开发，这就是Android NDK开发包，但Android提供NDK开发包的主要目的并不是推荐开发人员使用C（Native 代码）来编写一般的Android应用，而是要使用Java代码来编写Android应用来更好的处理Android应用生命周期(Life- cycle)相关的事件以避免出现&#8220;应用程序不响应（<a rel="nofollow" href="http://www.imobilebbs.com/wordpress/wp-content/uploads/2011/04/anr.png" style="text-decoration: none; color: #556c88;">ANR</a>）&#8221;的对话框。</p><p style="line-height: 28px; margin: 0px 0px 10px; padding: 0px; color: #333333; font-family: 'Hiragino Sans GB W3', 'Hiragino Sans GB', Arial, Helvetica, simsun, u5b8bu4f53; font-size: 16px; background-color: #ffffff;">使用NDK主要是通过<a rel="nofollow" href="http://en.wikipedia.org/wiki/Java_Native_Interface" style="text-decoration: none; color: #556c88;">JNI</a>&nbsp;使用从Java代码调用C代码，也就是使用Native编程主要是为上层Java代码提供库函数（动态库或是静态库的形式）而不是全部使用Native C代码编写整个Android应用（尽管借助于少量Java代码也是可以大部分使用C代码来实现的）。<span style="color: #0000ff;">使用NDK大部分情况是需要将一些已有的C函数库移植到Android平台的所选择的快捷方法，而不是作为提高代码效率的手段。</span></p><p style="line-height: 28px; margin: 0px 0px 10px; padding: 0px; color: #333333; font-family: 'Hiragino Sans GB W3', 'Hiragino Sans GB', Arial, Helvetica, simsun, u5b8bu4f53; font-size: 16px; background-color: #ffffff;">安装Android NDK的方法非常简单：打开网页<a rel="nofollow" href="http://developer.android.com/sdk/ndk/index.html" style="text-decoration: none; color: #556c88;">http://developer.android.com/sdk/ndk/index.html</a></p><p style="line-height: 28px; margin: 0px 0px 10px; padding: 0px; color: #333333; font-family: 'Hiragino Sans GB W3', 'Hiragino Sans GB', Arial, Helvetica, simsun, u5b8bu4f53; font-size: 16px; background-color: #ffffff;">选择合适的NDK开发包，下载解压即可。注：安装NDK之前需先安装SDK开发包，参见【<span style="font-family: verdana, 'courier new'; font-size: 14px; line-height: 21px;">Android简明开发教程二：安装开发环境。</span>】<br /></p><p style="line-height: 28px; margin: 0px 0px 10px; padding: 0px; color: #333333; font-family: 'Hiragino Sans GB W3', 'Hiragino Sans GB', Arial, Helvetica, simsun, u5b8bu4f53; font-size: 16px; background-color: #ffffff;">Android NDK 的前两级目录如下：</p><p style="line-height: 28px; margin: 0px 0px 10px; padding: 0px; color: #333333; font-family: 'Hiragino Sans GB W3', 'Hiragino Sans GB', Arial, Helvetica, simsun, u5b8bu4f53; font-size: 16px; background-color: #ffffff;"><br /></p><p style="line-height: 28px; margin: 0px 0px 10px; padding: 0px; color: #333333; font-family: 'Hiragino Sans GB W3', 'Hiragino Sans GB', Arial, Helvetica, simsun, u5b8bu4f53; font-size: 16px; background-color: #ffffff;">.<br />&#9500;&#9472;&#9472; build<br />&#9474;&nbsp;&nbsp; &#9500;&#9472;&#9472; awk<br />&#9474;&nbsp;&nbsp; &#9500;&#9472;&#9472; core<br />&#9474;&nbsp;&nbsp; &#9500;&#9472;&#9472; gmsl<br />&#9474;&nbsp;&nbsp; &#9492;&#9472;&#9472; tools<br /><span style="color: #0000ff;">&#9500;&#9472;&#9472; docs<br />&#9474;&nbsp;&nbsp; &#9500;&#9472;&#9472; ANDROID-ATOMICS.html<br />&#9474;&nbsp;&nbsp; &#9500;&#9472;&#9472; ANDROID-MK.html<br />&#9474;&nbsp;&nbsp; &#9500;&#9472;&#9472; APPLICATION-MK.html<br />&#9474;&nbsp;&nbsp; &#9500;&#9472;&#9472; CHANGES.html<br />&#9474;&nbsp;&nbsp; &#9500;&#9472;&#9472; CPLUSPLUS-SUPPORT.html<br />&#9474;&nbsp;&nbsp; &#9500;&#9472;&#9472; CPU-ARCH-ABIS.html<br />&#9474;&nbsp;&nbsp; &#9500;&#9472;&#9472; CPU-ARM-NEON.html<br />&#9474;&nbsp;&nbsp; &#9500;&#9472;&#9472; CPU-FEATURES.html<br />&#9474;&nbsp;&nbsp; &#9500;&#9472;&#9472; CPU-X86.html<br />&#9474;&nbsp;&nbsp; &#9500;&#9472;&#9472; DEVELOPMENT.html<br />&#9474;&nbsp;&nbsp; &#9500;&#9472;&#9472; HOWTO.html<br />&#9474;&nbsp;&nbsp; &#9500;&#9472;&#9472; IMPORT-MODULE.html<br />&#9474;&nbsp;&nbsp; &#9500;&#9472;&#9472; INSTALL.html<br />&#9474;&nbsp;&nbsp; &#9500;&#9472;&#9472; LICENSES.html<br />&#9474;&nbsp;&nbsp; &#9500;&#9472;&#9472; NATIVE-ACTIVITY.HTML<br />&#9474;&nbsp;&nbsp; &#9500;&#9472;&#9472; NDK-BUILD.html<br />&#9474;&nbsp;&nbsp; &#9500;&#9472;&#9472; NDK-GDB.html<br />&#9474;&nbsp;&nbsp; &#9500;&#9472;&#9472; NDK-STACK.html<br />&#9474;&nbsp;&nbsp; &#9500;&#9472;&#9472; openmaxal<br />&#9474;&nbsp;&nbsp; &#9500;&#9472;&#9472; opensles<br />&#9474;&nbsp;&nbsp; &#9500;&#9472;&#9472; OVERVIEW.html<br />&#9474;&nbsp;&nbsp; &#9500;&#9472;&#9472; PREBUILTS.html<br />&#9474;&nbsp;&nbsp; &#9500;&#9472;&#9472; sidenav.html<br />&#9474;&nbsp;&nbsp; &#9500;&#9472;&#9472; STABLE-APIS.html<br />&#9474;&nbsp;&nbsp; &#9500;&#9472;&#9472; STANDALONE-TOOLCHAIN.html<br />&#9474;&nbsp;&nbsp; &#9500;&#9472;&#9472; system<br />&#9474;&nbsp;&nbsp; &#9492;&#9472;&#9472; SYSTEM-ISSUES.html<br />&#9500;&#9472;&#9472; documentation.html<br /></span>&#9500;&#9472;&#9472; GNUmakefile<br />&#9500;&#9472;&#9472; ndk-build<br />&#9500;&#9472;&#9472; ndk-build.cmd<br />&#9500;&#9472;&#9472; ndk-gdb<br />&#9500;&#9472;&#9472; ndk-stack<br />&#9500;&#9472;&#9472; ndk.txt<br />&#9500;&#9472;&#9472; platforms<br />&#9474;&nbsp;&nbsp; &#9500;&#9472;&#9472; android-14<br />&#9474;&nbsp;&nbsp; &#9500;&#9472;&#9472; android-3<br />&#9474;&nbsp;&nbsp; &#9500;&#9472;&#9472; android-4<br />&#9474;&nbsp;&nbsp; &#9500;&#9472;&#9472; android-5<br />&#9474;&nbsp;&nbsp; &#9500;&#9472;&#9472; android-8<br />&#9474;&nbsp;&nbsp; &#9492;&#9472;&#9472; android-9<br />&#9500;&#9472;&#9472; prebuilt<br />&#9474;&nbsp;&nbsp; &#9492;&#9472;&#9472; linux-x86<br />&#9500;&#9472;&#9472; README.TXT<br />&#9500;&#9472;&#9472; RELEASE.TXT<br />&#9500;&#9472;&#9472; samples<br />&#9474;&nbsp;&nbsp; &#9500;&#9472;&#9472; bitmap-plasma<br />&#9474;&nbsp;&nbsp; &#9500;&#9472;&#9472; hello-gl2<br />&#9474;&nbsp;&nbsp; &#9500;&#9472;&#9472; hello-jni<br />&#9474;&nbsp;&nbsp; &#9500;&#9472;&#9472; hello-neon<br />&#9474;&nbsp;&nbsp; &#9500;&#9472;&#9472; module-exports<br />&#9474;&nbsp;&nbsp; &#9500;&#9472;&#9472; native-activity<br />&#9474;&nbsp;&nbsp; &#9500;&#9472;&#9472; native-audio<br />&#9474;&nbsp;&nbsp; &#9500;&#9472;&#9472; native-media<br />&#9474;&nbsp;&nbsp; &#9500;&#9472;&#9472; native-plasma<br />&#9474;&nbsp;&nbsp; &#9500;&#9472;&#9472; san-angeles<br />&#9474;&nbsp;&nbsp; &#9500;&#9472;&#9472; test-libstdc++<br />&#9474;&nbsp;&nbsp; &#9492;&#9472;&#9472; two-libs<br />&#9500;&#9472;&#9472; sources<br />&#9474;&nbsp;&nbsp; &#9500;&#9472;&#9472; android<br />&#9474;&nbsp;&nbsp; &#9500;&#9472;&#9472; cpufeatures<br />&#9474;&nbsp;&nbsp; &#9492;&#9472;&#9472; cxx-stl<br />&#9500;&#9472;&#9472; tests<br />&#9474;&nbsp;&nbsp; &#9500;&#9472;&#9472; awk<br />&#9474;&nbsp;&nbsp; &#9500;&#9472;&#9472; build<br />&#9474;&nbsp;&nbsp; &#9500;&#9472;&#9472; device<br />&#9474;&nbsp;&nbsp; &#9500;&#9472;&#9472; README<br />&#9474;&nbsp;&nbsp; &#9500;&#9472;&#9472; run-standalone-tests.sh<br />&#9474;&nbsp;&nbsp; &#9500;&#9472;&#9472; run-tests.sh<br />&#9474;&nbsp;&nbsp; &#9492;&#9472;&#9472; standalone<br />&#9492;&#9472;&#9472; toolchains<br />&nbsp;&nbsp;&nbsp; &#9500;&#9472;&#9472; arm-linux-androideabi-4.4.3<br />&nbsp;&nbsp;&nbsp; &#9492;&#9472;&#9472; x86-4.4.3</p><p style="line-height: 28px; margin: 0px 0px 10px; padding: 0px; color: #333333; font-family: 'Hiragino Sans GB W3', 'Hiragino Sans GB', Arial, Helvetica, simsun, u5b8bu4f53; font-size: 16px; background-color: #ffffff;">在开发NDK之前，建议先看一下doc 子目录下的文档，后面会有所介绍。</p><img src ="http://www.cppblog.com/xkjy3000/aggbug/204406.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/xkjy3000/" target="_blank">虚空骄阳</a> 2013-11-24 12:45 <a href="http://www.cppblog.com/xkjy3000/archive/2013/11/24/204406.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item></channel></rss>