A. ndk-android NDk 怎麼編譯時動態鏈接第三方so庫,有頭文件
問題描述:Android如何調用第三方SO庫;
已知條件:SO庫為Android版本連接庫(*.so文件),並提供了詳細的介面說明;
已了解解決方案:
1.將SO文件直接放到libs/armeabi下,然後代碼中System.loadLibrary("xxx");再public native static int xxx_xxx_xxx();接下來就可以直接調用xxx_xxx_xxx()方法;
2.第二種方案,創建自己的SO文件,在自己的SO文件里調用第三方SO,再在程序中調用自己的SO,這種比較復雜,需要建java類文件,生成.h文件,編寫C源文件include之前生成的.h文件並實現相應方法,最後用android NDK開發包中的ndk-build腳本生成對應的.so共享庫;
求解:
1.上面兩種方案是否可行?不可行的話存在什麼問題?
2.兩種方案有什麼區別?為什麼網上大部都是用的第二種方案?
3.只有一個*.so文件,並提供了詳細的介面說明,是否可在ANDROID中使用它?
首先要看這個SO是不是JNI規范的SO,比如有沒有返回JNI不直接支持的類型。也就是說這個SO是不是可以直接當作JNI來調用。如果答案是否定的,你只能選第二個方案。
如果答案是肯定的,還要看你是不是希望這個SO的庫直接暴露給JAVA層,如果答案是否定的,你只能選第二個方案,比如你本身也是一個庫的提供者。
一般如果你只有SO,就說明這個是別人提供給你的,你可以要求對方給你提供配套的JAVA調用文件。
1、這個要看這個SO是不是符合JNI調用的規范。還要看你自己的意願。
2、因為第二種方法最靈活,各種情況都可以實現。
3、可以
看能不能直接從JAVA調用的最簡單的方法就是看SO里的函數名是不是Java_XXX_XXX_XXX格式的
是就可以,你可以自己寫一個配套的JAVA文件,注意一下SO函數名和JAVA函數名的轉換規則,或者向SO提供方索要;
不是的話就選第二種方案吧。
1、檢查所需文件是否齊全
使用第三方動態庫,應該至少有2個文件,一個是動態庫(.so),另一個是包含
動態庫API聲明的頭文件(.h)
2、封裝原動態庫
原動態庫文件不包含jni介面需要的信息,所以我們需要對其進行封裝,所以我
們的需求是:將libadd.so 裡面的API封裝成帶jni介面的動態
3、編寫庫的封裝函數libaddjni.c
根據前面生成的com_android_libjni_LibJavaHeader.h 文件,編寫libaddjni.c,用
來生成libaddjni.so
Android中集成第三方軟體包(.jar, .so)
Android中可能會用到第三方的軟體包,這包括Java包.jar和Native包.so。jar包既可通過Eclipse開發環境集成,也可通過編譯源碼集成,看你的工作環境。
假定自己開發的程序為MyMaps,需要用到BaiMaps的庫,包括mapapi.jar和libBMapApiEngine_v1_3_1.so。
一、Eclipse中集成第三方jar包及.so動態庫
MyMaps工程下創建目錄libs以及libs/armeabi,把mapapi.jar放在的libs/目錄下,把libBMapApiEngine_v1_3_1.so放在libs/armeabi/下。
Eclipse中把第三方jar包mapapi.jar打包到MyMaps的步驟:
1. 右擊工程,選擇Properties;
2. Java Build Path,選擇Libraries;
3. Libraries頁面點擊右面按鈕「Add Library…」;
4. 選擇「User Library」,點擊「Next」;
5. 點擊「User Libraries」按鈕;
6. 在彈出界面中,點擊「New…」;
7. 輸入「User library name」,點擊「OK」確認;
8. 返回之後,選擇剛剛創建的User library,右面點擊「AddJARs」;
9. 選擇MyMaps/libs/下的mapapi.jar;
10. 確認,返回。
這樣,編譯之後,該jar包就會被打進MyMaps.apk中,libBMapApiEngine_v1_3_1.so也被打包在lib/armeabi/中。
程序運行過程中,libBMapApiEngine_v1_3_1.so被放在/data/data/<yourAppPackage>/lib/下,載入動態庫時系統會從程序的該lib/目錄下查找.so庫。
二、源碼中集成第三方集成jar包及.so動態庫
Android源碼中MyMaps放在packages/apps下。MyMaps下創建目錄libs以及libs/armeabi,並把mapapi.jar放在libs/,把libBMapApiEngine_v1_3_1.so放在libs/armeabi。
2.1 修改Android.mk文件
Android.mk文件如下:
[plain] view plain
LOCAL_PATH:= $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE_TAGS := optional
LOCAL_STATIC_JAVA_LIBRARIES := libmapapi
LOCAL_SRC_FILES := $(call all-subdir-java-files)
LOCAL_PACKAGE_NAME := MyMaps
include $(BUILD_PACKAGE)
##################################################
include $(CLEAR_VARS)
LOCAL_PREBUILT_STATIC_JAVA_LIBRARIES :=libmapapi:libs/mapapi.jar
LOCAL_PREBUILT_LIBS :=libBMapApiEngine_v1_3_1:libs/armeabi/libBMapApiEngine_v1_3_1.so
LOCAL_MODULE_TAGS := optional
include $(BUILD_MULTI_PREBUILT)
# Use the following include to make our testapk.
include $(callall-makefiles-under,$(LOCAL_PATH))
1 集成jar包
LOCAL_STATIC_JAVA_LIBRARIES取jar庫的別名,可以任意取值;
LOCAL_PREBUILT_STATIC_JAVA_LIBRARIES指定prebuiltjar庫的規則,格式:別名:jar文件路徑。注意:別名一定要與LOCAL_STATIC_JAVA_LIBRARIES里所取的別名一致,且不含.jar;jar文件路徑一定要是真實的存放第三方jar包的路徑。
編譯用BUILD_MULTI_PREBUILT。
2 集成.so動態庫
LOCAL_PREBUILT_LIBS指定prebuilt so的規則,格式:別名:so文件路徑。注意:別名一般不可改變,特別是第三方jar包使用.so庫的情況,且不含.so;so文件路徑一定要是真實的存放第三方so文件的路徑。
編譯拷貝用BUILD_MULTI_PREBUILT。
2.2 加入到GRANDFATHERED_USER_MODULES
在文件user_tags.mk中,把libBMapApiEngine_v1_3_1加入到GRANDFATHERED_USER_MODULES中
[plain] view plain
GRANDFATHERED_USER_MODULES += \
… \
libBMapApiEngine_v1_3_1
user_tags.mk可以是build/core下的,也可以是$(TARGET_DEVICE_DIR)下的,推薦修改$(TARGET_DEVICE_DIR)下的。
2.3 編譯結果
MyMaps.apk編譯生成在out/target/proct/<YourProct>/system/app/下;
libBMapApiEngine_v1_3_1.so放在out/target/proct/<YourProct>/system/lib/下,這也是系統載入動態庫時搜索的路徑。
B. 如何製作app軟體
隨著移動手機的普及,移動APP應用軟體也流行起來。「啟匯網路」市場部通過調查得出一組數據:20%左右的企業已經擁有或者正在開發自己的app應用軟體,60%左右的公司已經把開發app軟體列入近期公司發展項目中。可以看出,大部分公司和站長都有想法把自己的網站製作成app軟體,跟緊潮流步伐。但app開發涉及到的技術比較專業,開發語言要想熟悉掌握也並非一件易事。那麼,在技術還未過關的情況下,如何製作app應用軟體呢?
接下來,我將給大家介紹一些適合製作簡單app的軟體,讓各位在未掌握app開發語言情況下,依然能製作出屬於自己的app應用軟體。
一:Appmakr
AppMakr是一個可以讓你在幾分鍾之內創建應用程序的一種服務,無需編碼能力。使用該工具,你可以創建iPhone和Android應用。還有一些可供選擇的功能,包括將網站連接到你的應用程序、HTML5功能、推送通知和廣告支持。通過AppMaker賬戶,你可以創建無限數量的應用程序。
目前Appmakr是國外比較流行的應用生成工具,在國內也享有一定知名度。
二:AppCan
AppCan屬於移動應用開發平台,應用引擎支持Hybrid
App的開發和運行。並且著重解決了基於HTML5的移動應用目前"不流暢"和"體驗差"的問題。使用AppCan應用引擎提供的Native交互能力,可以讓HTML5開發的移動應用基本接近Native
App的體驗。
與Phonegap支持單一webview使用div為單位開發移動應用不同。AppCan支持多窗口機制,讓開發者可以像最傳統的網頁開發一樣,通過頁面鏈接的方式靈活的開發移動應用。基於這種機制,開發者可以開發出大型的移動應用,而不是只能開發簡易類型的移動應用。
三:appBook
appBook平台是多平台移動應用製作工具,可以廣泛用於書籍製作,個人雜志發行,宣傳手冊,支持iPad、iPhone、Andriod等平台,不支持pc平台。真正做到了一次編譯多平台發布。目前appbook平台有:iebook平台、及、appbook應用製作平台.
曾經我也適用用軟體製作APP,目的是達到了,但做出來的app比較生硬。後來我和啟匯網路(廣州一家比較專業的APP開發公司)技術總監Daniel聊起app開發,Daniel認為:要做好app開發,必須要有核心的app開發技術,有經驗的app開發團隊,才能做好滿意的app應用軟體。
真正要做好一個APP,也要掌握一定的app開發技術才是王道!
Tag:如何製作app,app移動應用,app外包公司,app客戶端製作
C. 求解 java動態編譯找不到類,往各位大蝦指導
參照網上其他童鞋的例子與介紹,修改了一下:
import java.io.IOException;
import java.lang.reflect.Method;
import java.net.URI;
import java.net.URISyntaxException;
import java.util.Arrays;
import javax.tools.JavaCompiler;
import javax.tools.JavaCompiler.CompilationTask;
import javax.tools.JavaFileObject;
import javax.tools.SimpleJavaFileObject;
import javax.tools.StandardJavaFileManager;
import javax.tools.ToolProvider;
/**
* 動態編譯Java 源文件
*
* @author shenshouer
*
*/
public class CompilerTest {
public static void main(String[] args) throws Exception {
String source = "public class Main { " + "public static void main(String[]args) {"
+ "System.out.println(\"Hello World!\");" + "} " + "}";
JavaCompiler compiler = ToolProvider.getSystemJavaCompiler();
StandardJavaFileManager fileManager = compiler.getStandardFileManager(null, null, null);
StringSourceJavaObject sourceObject = new CompilerTest.StringSourceJavaObject("Main",
source);
Iterable<? extends JavaFileObject> fileObjects = Arrays.asList(sourceObject);
// 獲取編譯類根路徑,不然會報找不到類的錯誤
String path = Class.class.getClass().getResource("/").getPath();
Iterable< String> options = Arrays.asList("-d", path);
// 增加options參數
// CompilationTask task = compiler.getTask(null, fileManager, null, null, null, fileObjects);
CompilationTask task = compiler.getTask(null, fileManager, null, options, null, fileObjects);
boolean result = task.call();
if (result) {
System.out.println("編譯成功。");
ClassLoader loader = CompilerTest.class.getClassLoader();
try {
Class<?> clazz = loader.loadClass("Main");
Method method = clazz.getMethod("main", String[].class);
// 修改調用參數,不然會報參數個數不對
// Object value = method.invoke(null, new Object[] {});
Object value = method.invoke(null, new Object[] {new String[]{}});
System.out.println(value);
} catch (Exception e) {
e.printStackTrace();
}
}
}
static class StringSourceJavaObject extends SimpleJavaFileObject {
private String content = null;
public StringSourceJavaObject(String name, String content) throws URISyntaxException {
super(URI.create("string:///" + name.replace('.', '/') + Kind.SOURCE.extension),
Kind.SOURCE);
this.content = content;
}
public CharSequence getCharContent(boolean ignoreEncodingErrors) throws IOException {
return content;
}
}
}
D. 易語言沒Widows動態鏈接庫怎麼編譯生成安裝軟體。
的意見作了一些修改。
什麼是一個高效的軟體?一個高效的軟體不僅應該比實現同樣功能的軟體運行得更快,還應該消耗更少的系統資源。程序的時間效率是指運行速度,空間效率是指程序佔用內存或者外存的狀況。另外程序的效率我們也可以分為全局效率和局部效率。全局效率是指站在整個系統的角度上考慮的效率,局部效率是指站在模塊或函數角度上考慮的效率。
1. 使用整數和長整數
提高代碼運行速度最簡單的方法莫過於使用正確的數據類型了。也許你不相信,但是正確地選擇數據類型可以大幅度提升代碼的性能。在大多數情況下,程序員可以將短整數型、小數型和雙精度小數型的變數替換為整數(Integer)或長整數(Long)類型的變數,因為易語言處理整數和長整數的能力遠遠高於處理其它幾種數據類型。
在大多數情況下,程序員選擇使用小數型或雙精度小數型的原因是因為它們能夠保存小數。但是小數也可以保存在整數類型的變數中。例如程序中約定有三位小數,那麼只需要將保存在整數型變數中的數值除以1000就可以得到結果。根據我的經驗,使用整數和長整數替代短整數型、小數型和雙精度小數型後,代碼的運行速度可以提高將近10倍。 但是我們也不要老是強調使用使用整數和長整數,因為在程序中數據類型的定義還牽涉一個關鍵的問題,就是數據的安全,頻繁而無規范地定義 數據類型會使演算法出現漏洞,是數據的安全和臨界判斷有問題.對財務和工程計算而言,小數點的精度是很敏感的數據,只能用雙精度數據來規范.另外, 換成整型也會導致程序可讀性急劇下降.
2. 避免使用通用型數據
通用型的變數需要16個位元組的空間來保存數據,而一個整數(Integer)只需要2個位元組。通常使用通用型變數的目的是為了減少設計的工作量和代碼量,也有的程序員圖個省事而使用它。但是如果一個軟體經過了嚴格設計和按照規范編碼的話,完全可以避免使用變體類型。
3. 盡量避免使用屬性
在平時的代碼中,最常見的比較低效的代碼就是在可以使用變數的情況下,反復使用屬性(Property),尤其是在循環中。要知道存取變數的速度是存取屬性的速度的20倍左右。下面這段代碼是很多程序員在程序中會使用到的:
容器名: 數值 類型:整數型容器名: 容器 類型:整數型 計次循環首(7,容器) 文本1.內容 = 文本1.內容 + #換行符 + 到文本((數值×容器))計次循環尾()
下面這段代碼的執行速度是上面代碼的20倍。
容器名: 數值 類型:整數型容器名: 容器 類型:整數型容器名: 文本 類型:文本型
文本 = 文本1.內容 計次循環首(7,容器) 文本 = 文本 + #換行符 + 到文本((數值×容器))計次循環尾()文本1.內容 = 文本
另外要注意,這個涉及一個編程思路, 用屬性當變數的作法大多數情況可以簡化演算法。所以有時候也不能一味強調用變數代替屬性。
6. 避免調用很短的子程序
調用只有幾行代碼的子程序也是不經濟的--調用子程序所花費的時間或許比執行子程序中的代碼需要更長的時間。在這種情況下,你可以把子程序中的代碼拷貝到原來調用子程序的地方。 但是有時候小的子程序可能會被調用很多次而不是只有兩三次,這時就應該調用它。
7. 減少對子對象的引用
在易語言中,通過使用.來實現對象的引用。例如:
窗口1.編輯框1.內容
在上面的例子中,程序引用了兩個對象:窗口1和編輯框1。利用這種方法引用效率很低。但遺憾的是,沒有辦法可以避免它。我的「多媒體模塊」就有這個缺點。
8. 檢查文本型數據是否為空
大多數易語言用戶在檢查文本型數據是否為空時會使用下面的方法:
如果 (文本1.內容 = "" ) 注釋: 執行操作 結束如果
很不幸,進行字元串比較需要的處理量甚至比讀取屬性還要大。因此我建議大家使用下面的方法:
如果 (到數值(文本1.內容) = 0 ) 注釋: 執行操作 結束如果
另一個不同的意見是:問題在於當文本字串為 "ABC"之類的非數值型時, 到數值("ABC")=0並不表示為空。文本比較的效率並不低,在底層演算法中,一般會直接比較長度才會繼續比較內容。
9. 使用數組,而不是多個變數
當你有多個保存類似數據的變數時,可以考慮將他們用一個數組代替。在易語言中,數組是最高效的數據結構之一。
10. 盡量使用動態數組,而不是靜態數組
使用動態數組對代碼的執行速度不會產生太大的影響,但是在某些情況下可以節約大量的資源。
11. 銷毀對象
無論編寫的是什麼軟體,程序員都需要考慮在用戶決定終止軟體運行後釋放軟體佔用的內存空間。但遺憾的是很多用戶對這一點好像並不是很在意。正確的做法是在退出程序前需要銷毀程序中使用的對象。例如:關閉資料庫:關閉(資料庫名稱)、全部關閉(),關閉打開(播放)的文件,關閉載入的圖片等。 中止程序執行時應該要關閉打開的文件(包括資料庫文件、圖片文件等),但是窗口銷毀對銷毀窗口及窗口單元來說是自動的,已足夠做釋放用,在窗口內最好不要隨意銷毀窗口單元,可能會導致程序運行中的潛在的單元數據訪問而崩潰.只有在圖形buffer情況才需要經常銷毀。
12. 盡量使用內部子程序,減少易模塊的數量
因為從易語言連接到一個外部對象需要耗費大量的CPU處理能力。每當你調用介面函數的時候,都會浪費大量的系統資源。 另外只有在易模塊中的介面函數或變數被調用時,易語言才將易模塊載入到內存中;當易語言應用程序退出時,才會從內存中卸載這些模塊。如果代碼中只有一個模塊,易語言就只會進行一次載入操作,這樣代碼的效率就得到了提高;反之如果代碼中有多個模塊,易語言會進行多次載入操作,代碼的效率會降低。
13. 使用對象數組
當設計用戶界面時,對於同樣類型的控制項,程序員應該盡量使用對象數組。你可以做一個實驗:在窗口上添加100個圖片框,每個圖片框都有不同的名稱,運行程序。然後創建一個新的工程,同樣在窗口上添加100個圖片框,不過這一次使用對象數組,運行程序,你可以注意到兩個程序載入時間上的差別。 也有人認為兩者從邏輯上看效率應該差不多。
14. 使用窗口單元「移動」方法
在改變對象的位置時,有些用戶喜歡使用「寬度」、「高度」、「頂邊」和「左邊」屬性。例如:
按鈕1.寬度 = 100 按鈕1.高度 = 100 按鈕1.頂邊 = 0 按鈕1.左邊 = 0
實際上這樣做效率很低,因為程序修改了四個屬性,而且每次修改之後,窗口都會被重繪。正確的做法是使用Move方法:
按鈕1.移動(0,0,100,100)
15. 減少圖片的使用
圖片將佔用大量內存,而且處理圖片也需要佔用很多CPU資源。在軟體中,如果可能的話,可以考慮用背景色來替代圖片--當然這只是從技術人員的角度出發看這個問題。 但是如果為了優化程序界面,使用圖形換來的好處可能遠勝節約下的資源,否則就不會有XP,也不會有游戲的進步了。
16. 編譯優化
易語言的程序編譯有三個選項:「編譯」、「獨立編譯」、「編譯生成安裝軟體」。優先使用的次序應該是「編譯生成安裝軟體」、「編譯」、「獨立編譯」,因為「獨立編譯」會將易語言系統中所有的支持庫都編譯進去,而「編譯生成安裝軟體」只選擇程序中必要的支持庫編譯。要脫離易語言環境也可以運行,就不要使用「編譯」而應用「編譯生成安裝軟體」或「獨立編譯」。 總結:執行效率和程序可讀性永遠是對矛盾 ,兩者應該通盤考慮;資源佔用和程序易用性永遠是對矛盾,兩者也應該通盤考慮。基於此,下面探討一些提高程序的效率的規則。
不要一味地追求程序的效率,應當在滿足正確性、可靠性、健壯性、可讀性等質量因素的前提下,設法提高程序的效率。
以提高程序的全局效率為主,提高局部效率為輔。
在優化程序的效率時,應當先找出限制效率的「瓶頸」,不要在無關緊要之處優化。
先優化數據結構和演算法,再優化執行代碼。先考慮某功能是否可以用函數(命令)來實現,如果找不到這樣的函數,再考慮用其他代碼實現。
有時候時間效率和空間效率可能對立,此時應當分析那個更重要,作出適當的折衷。例如多花費一些內存來提高性能。
不要在什麼時候都只追求緊湊的代碼,因為緊湊的代碼並不能產生高效的機器碼。
E. openssl怎麼編譯成動態庫
1、靜態編譯
./Configure linux-elf-arm -DB_ENDIAN linux:'armeb-linux-gcc -mbig-endian' --prefix=$(pwd)/OpenSSL
a、 將openssl-0.9.8d/crypto/bio/bss_file.c中以下代碼注釋掉
//#ifndef _FILE_OFFSET_BITS
//#define _FILE_OFFSET_BITS 64
//#endif
#endif
b、 報錯沒有timeb.h時,在報錯的.c文件中#undef TIMEB
c、 去掉openssl頂層Makefile中「build_all:」後面的 build_app build_test (我們要的只是兩個靜態庫libcrypto.a和libssl.a),並去掉」DIRS=」後面的app和tests。
make && make install
2、動態庫
1.config:
#config no-asm --prefix=../OpenSSL
2.改Makefile
1) CC= gcc 改成 CC = armeb-linux-gcc;
2) 刪除 CFLAG= 中的 「-march=pentium」;
3) AR=ar $(ARFLAGS) r 改為 AR=armeb-linux-ar $(ARFLAGS) r;
4) ARD=ar $(ARFLAGS) d 改為 ARD=armeb-linux-ar $(ARFLAGS) d;
5)RANLIB= /usr/bin/ranlib 改為 RANLIB= armeb-linux-ranlib;
3.編譯
#make
#make install
F. viewbag 找不到編譯動態表達式
1 刪除C:Users{your computer name}AppDataLocalTempTemporary ASP.NET Files 該目錄下的臨時文件(親試無效)
2 把配置文件改了也無無效.
好奇怪,就某個項目出現這個情況. 其他項目正常
G. 如何讓編譯器架構Android.mk動態
Android.mk文件用來告知NDK Build 系統關於Source的信息。 Android.mk將是GNU Makefile的一部分,且將被Build System解析一次或多次。
所以,請盡量少的在Android.mk中聲明變數,也不要假定任何東西不會在解析過程中定義。
Android.mk文件語法允許我們將Source打包成一個"moles". moles可以是:
靜態庫
動態庫。
只有動態庫可以被 install/到應用程序包(APK). 靜態庫則可以被鏈接入動態庫。
可以在一個Android.mk中定義一個或多個moles. 也可以將同一份source 加進多個moles.
Build System幫我們處理了很多細節而不需要我們再關心。例如:你不需要在Android.mk中列出頭文件和外部依賴文件。
NDK Build System自動幫我們提供這些信息。這也意味著,當用戶升級NDK後,你將可以受益於新的toolchain/platform而不必再去修改Android.mk.
1. Android.mk語法:
首先看一個最簡單的Android.mk的例子:
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE := hello-jni
LOCAL_SRC_FILES := hello-jni.c
include $(BUILD_SHARED_LIBRARY)
講解如下:
LOCAL_PATH := $(call my-dir)
每個Android.mk文件必須以定義LOCAL_PATH為開始。它用於在開發tree中查找源文件。
宏my-dir則由Build System提供。返回包含Android.mk的目錄路徑。
include $(CLEAR_VARS)
CLEAR_VARS 變數由Build System提供。並指向一個指定的GNU Makefile,由它負責清理很多LOCAL_xxx.
例如:LOCAL_MODULE, LOCAL_SRC_FILES, LOCAL_STATIC_LIBRARIES等等。但不清理LOCAL_PATH.
這個清理動作是必須的,因為所有的編譯控制文件由同一個GNU Make解析和執行,其變數是全局的。所以清理後才能避免相互影響。
LOCAL_MODULE := hello-jni
LOCAL_MODULE模塊必須定義,以表示Android.mk中的每一個模塊。名字必須唯一且不包含空格。
Build System會自動添加適當的前綴和後綴。例如,foo,要產生動態庫,則生成libfoo.so. 但請注意:如果模塊名被定為:libfoo.則生成libfoo.so. 不再加前綴。
LOCAL_SRC_FILES := hello-jni.c
LOCAL_SRC_FILES變數必須包含將要打包如模塊的C/C++ 源碼。
不必列出頭文件,build System 會自動幫我們找出依賴文件。
預設的C++源碼的擴展名為.cpp. 也可以修改,通過LOCAL_CPP_EXTENSION。
include $(BUILD_SHARED_LIBRARY)
BUILD_SHARED_LIBRARY:是Build System提供的一個變數,指向一個GNU Makefile Script。
它負責收集自從上次調用 include $(CLEAR_VARS) 後的所有LOCAL_XXX信息。並決定編譯為什麼。
BUILD_STATIC_LIBRARY:編譯為靜態庫。
BUILD_SHARED_LIBRARY :編譯為動態庫
BUILD_EXECUTABLE:編譯為Native C可執行程序
2. NDK Build System變數:
NDK Build System 保留以下變數名:
以LOCAL_ 為開頭的
以PRIVATE_ ,NDK_ 或者APP_ 開頭的名字。
小寫字母名字:如my-dir
如果想要定義自己在Android.mk中使用的變數名,建議添加 MY_前綴。
2.1: NDK提供的變數:
此類GNU Make變數是NDK Build System在解析Android.mk之前就定義好了的。
2.1.1:CLEAR_VARS:
指向一個編譯腳本。必須在新模塊前包含之。
include $(CLEAR_VARS)
2.1.2:BUILD_SHARED_LIBRARY:
指向一個編譯腳本,它收集自從上次調用 include $(CLEAR_VARS) 後的所有LOCAL_XXX信息。
並決定如何將你列出的Source編譯成一個動態庫。 注意,在包含此文件前,至少應該包含:LOCAL_MODULE and LOCAL_SRC_FILES 例如:
include $(BUILD_SHARED_LIBRARY)
2.1.3:BUILD_STATIC_LIBRARY:
與前面類似,它也指向一個編譯腳本,
收集自從上次調用 include $(CLEAR_VARS) 後的所有LOCAL_XXX信息。
並決定如何將你列出的Source編譯成一個靜態庫。 靜態庫不能夠加入到Project 或者APK中。但它可以用來生成動態庫。
LOCAL_STATIC_LIBRARIES and LOCAL_WHOLE_STATIC_LIBRARIES將描述之。
include $(BUILD_STATIC_LIBRARY)
2.1.4: BUILD_EXECUTABLE:
與前面類似,它也指向一個編譯腳本,收集自從上次調用 include $(CLEAR_VARS) 後的所有LOCAL_XXX信息。
並決定如何將你列出的Source編譯成一個可執行Native程序。 include $(BUILD_EXECUTABLE)
2.1.5:PREBUILT_SHARED_LIBRARY:
把這個共享庫聲明為 「一個」 獨立的模塊。
指向一個build 腳本,用來指定一個預先編譯好多動態庫。 與BUILD_SHARED_LIBRARY and BUILD_STATIC_LIBRARY不同,
此時模塊的LOCAL_SRC_FILES應該被指定為一個預先編譯好的動態庫,而非source file. LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE := foo-prebuilt # 模塊名
LOCAL_SRC_FILES := libfoo.so # 模塊的文件路徑(相對於 LOCAL_PATH)
include $(PREBUILT_SHARED_LIBRARY) # 注意這里不是 BUILD_SHARED_LIBRARY
這個共享庫將被拷貝到 $PROJECT/obj/local 和 $PROJECT/libs/<abi> (stripped) 主要是用在將已經編譯好的第三方庫
使用在本Android Project中。為什麼不直接將其COPY到libs/armabi目錄呢?因為這樣做缺陷很多。下一節再詳細說明。
2.1.6: PREBUILT_STATIC_LIBRARY:預先編譯的靜態庫。 同上。
2.1.7: TARGET_ARCH: 目標CPU架構名。如果為「arm」 則聲稱ARM兼容的指令。與CPU架構版本無關。
2.1.8: TARGET_PLATFORM: 目標的名字。
2.1.9:TARGET_ARCH_ABI
Name of the target CPU+ABI
armeabi For ARMv5TE armeabi-v7a
2.1.10:TARGET_ABI
2.2: NDK提供的功能宏:
GNUMake 提供的功能宏,只有通過類似: $(call function) 的方式來得到其值,它將返迴文本化的信息。
2.2.1: my-dir: $(call my-dir):
返回最近一次include的Makefile的路徑。通常返回Android.mk所在的路徑。它用來作為Android.mk的開頭來定義LOCAL_PATH. LOCAL_PATH := $(call my-dir)
請注意:返回的是最近一次include的Makefile的路徑。所以在Include其它Makefile後,再調用$(call my-dir)會返回其它Android.mk 所在路徑。 例如:
LOCAL_PATH := $(call my-dir) declare one mole include $(LOCAL_PATH)/foo/Android.mk LOCAL_PATH := $(call my-dir) declare another mole
則第二次返回的LOCAL_PATH為:$PATH/foo。 而非$PATH.
2.2.2: all-subdir-makefiles:
返回一個列表,包含'my-dir'中所有子目錄中的Android.mk。
例如: 結構如下: sources/foo/Android.mk sources/foo/lib1/Android.mk sources/foo/lib2/Android.mk
在If sources/foo/Android.mk 中, include $(call all-subdir-makefiles) 那則自動include 了sources/foo/lib1/Android.mk and sources/foo/lib2/Android.mk。
2.2.3:this-makefile:
當前Makefile的路徑。
2.2.4:parent-makefile:
返回include tree中父Makefile 路徑。 也就是include 當前Makefile的Makefile Path。
2.2.5:import-mole:
允許尋找並inport其它moles到本Android.mk中來。 它會從NDK_MODULE_PATH尋找指定的模塊名。 $(call import-mole,<name>)
2.3: 模塊描述變數:
此類變數用來給Build System描述模塊信息。在'include $(CLEAR_VARS)' 和 'include $(BUILD_XXXXX)'之間。必須定義此類變數。 include $(CLEAR_VARS) script用來清空這些變數。
include $(BUILD_XXXXX)收集和使用這些變數。
2.3.1: LOCAL_PATH:
這個值用來給定當前目錄。必須在Android.mk的開是位置定義之。
例如: LOCAL_PATH := $(call my-dir) LOCAL_PATH不會被include $(CLEAR_VARS) 清理。
2.3.2: LOCAL_MODULE:
moles名。在include $(BUILD_XXXXX)之前,必須定義這個變數。此變數必須唯一且不能有空格。
通常,由此變數名決定最終生成的目標文件名。
2.3.3: LOCAL_MODULE_FILENAME:
可選。用來override LOCAL_MODULE. 即允許用戶重新定義最終生成的目標文件名。 LOCAL_MODULE := foo-version-1 LOCAL_MODULE_FILENAME := libfoo
2.3.4:LOCAL_SRC_FILES:
為Build Moles而提供的Source 文件列表。不需要列出依賴文件。 注意:文件相對於LOCAL_PATH存放,
且可以提供相對路徑。 例如: LOCAL_SRC_FILES := foo.c \ toto/bar.c
2.3.5: LOCAL_CPP_EXTENSION:
指出C++ 擴展名。(可選) LOCAL_CPP_EXTENSION := .cxx 從NDK R7後,可以寫多個:
LOCAL_CPP_EXTENSION := .cxx .cpp .cc
2.3.6:LOCAL_CPP_FEATURES:
可選。用來指定C++ features。 LOCAL_CPP_FEATURES := rtti
LOCAL_CPP_FEATURES := exceptions
2.3.7:LOCAL_C_INCLUDES:
一個可選的path列表。相對於NDK ROOT 目錄。編譯時,將會把這些目錄附上。 LOCAL_C_INCLUDES := sources/foo LOCAL_C_INCLUDES := $(LOCAL_PATH)/../foo
2.3.8: LOCAL_CFLAGS:
一個可選的設置,在編譯C/C++ source 時添加如Flags。
用來附加編譯選項。 注意:不要嘗試在此處修改編譯的優化選項和Debug等級。它會通過您Application.mk中的信息自動指定。
也可以指定include 目錄通過:LOCAL_CFLAGS += -I<path>。 這個方法比使用LOCAL_C_INCLUDES要好。因為這樣也可以被ndk-debug使用。
2.3.9: LOCAL_CXXFLAGS: LOCAL_CPPFLAGS的別名。
2.3.10: LOCAL_CPPFLAGS:
C++ Source 編譯時添加的C Flags。這些Flags將出現在LOCAL_CFLAGS flags 的後面。
2.3.11: LOCAL_STATIC_LIBRARIES:
要鏈接到本模塊的靜態庫list。(built with BUILD_STATIC_LIBRARY)
2.3.12: LOCAL_SHARED_LIBRARIES:
要鏈接到本模塊的動態庫。
2.3.13:LOCAL_WHOLE_STATIC_LIBRARIES:
靜態庫全鏈接。 不同於LOCAL_STATIC_LIBRARIES,類似於使用--whole-archive
2.3.14:LOCAL_LDLIBS:
linker flags。 可以用它來添加系統庫。 如 -lz: LOCAL_LDLIBS := -lz
2.3.15: LOCAL_ALLOW_UNDEFINED_SYMBOLS:
2.3.16: LOCAL_ARM_MODE:
預設模式下,ARM目標代碼被編譯為thumb模式。每個指令16位。如果指定此變數為:arm。 則指令為32位。 LOCAL_ARM_MODE := arm 其實也可以指定某一個或者某幾個文件的ARM指令模式。
2.3.17: LOCAL_ARM_NEON:
設置為true時,會講浮點編譯成neon指令。這會極大地加快浮點運算(前提是硬體支持)
只有targeting 為 'armeabi-v7a'時才可以。
2.3.18:LOCAL_DISABLE_NO_EXECUTE:
2.3.19: LOCAL_EXPORT_CFLAGS:
定義這個變數用來記錄C/C++編譯器標志集合,
並且會被添加到其他任何以LOCAL_STATIC_LIBRARIES和LOCAL_SHARED_LIBRARIES的模塊的LOCAL_CFLAGS定義中 LOCAL_SRC_FILES := foo.c bar.c.arm
注意:此處NDK版本為NDK R7C.(不同NDK版本,ndk-build所產生的Makefile並不完全相同)
H. 100分求三菱plc編譯和模擬軟體(中文版),可以動態演示和操作!
已經把中文版GX simulator 和 GX-Developer 發到你有郵箱中,請查收。
I. 編程用那個軟體好用
如果您想學習編程,卻又不知從何入手,那麼您不妨看看下面的幾種學習方案,可能會給您一些啟示吧!
方案一 Basic語言 & Visual Basic
優點
(1)Basic 簡單易學,很容易上手。
(2)Visual Basic 提供了強大的可視化編程能力,可以讓你輕松地做出漂亮的程序。
(3)眾多的控制項讓編程變得象壘積木一樣簡單。
(4)Visual Basic 的全部漢化讓我們這些見了English就頭大的人喜不自禁。
缺點
(1)Visual Basic 不是真正的面向對象的開發文具。
(2)Visual Basic 的數據類型太少,而且不支持指針,這使得它的表達能力很有限。
(3)Visual Basic 不是真正的編譯型語言,它產生的最終代碼不是可執行的,是一種偽代碼。它需要一個動態鏈接庫去解釋執行,這使得Visual Basic 的編譯速度大大變慢。
綜述:方案一適合初涉編程的朋友,它對學習者的要求不高,幾乎每個人都可以在一個比較短的時間里學會vB編程,並用VB 做出自己的作品。對於那些把編程當做游戲的朋友來說,VB 是您最佳的選擇。
方案二 Pascal語言 & Delphi
優點
(1)Pascal語言結構嚴謹,可以很好地培養一個人的編程思想。
(2)Delphi是一門真正的面向對象的開發工具,並且是完全的可視化。
(3)Delphi使用了真編譯,可以讓你的代碼編譯成為可執行的文件,而且編譯速度非常快。
(4)Delphi具有強大的資料庫開發能力,可以讓你輕松地開發資料庫。
缺點
Delphi幾乎可以說是完美的,只是Pascal語言的過於嚴謹讓人感覺有點煩。
綜述: 方案二比較適合那些具有一定編程基礎並且學過Pascal語言的朋友。
方案三 C語言 & Visual C++
優點
(1)C語言靈活性好,效率高,可以接觸到軟體開發比較底層的東西。
(2)微軟的MFC庫博大精深,學會它可以讓隨心所欲地進行編程。
(3)VC是微軟製作的產品,與操作系統的結合更加緊密。
缺點
對使用者的要求比較高,既要具備豐富的C語言編程經驗,又要具有一定的WINDOWS編程基礎,它的過於專業使得一般的編程愛好者學習起來會有不小的困難。
綜述: VC是程序員用的東西。如果你是一個永不滿足的人,而且可以在編程上投入很大的精力和時間,那麼學習VC你一定不會後悔的。
方案四 C++語言 & C++ Builder
優點
(1)C++語言的優點全部得以繼承。
(2)完全的可是化。
(3)極強的兼容性,支持OWL、VCL和MFC三大類庫。
(4)編譯速度非常快。
缺點
由於推出的時間太短,關於它的各種資料還不太多。
綜述:我認為C++ Builder 是最好的編程工具。它既保持了C++語言編程的優點,又做到了完全的可視化。
方案五 SQL語言 & Power Builder
對於一些傳統的數據開發人員來說,Foxpro系列也許讓他們感到更加熟悉。但是對於初學者來說,PowerBuilder也許是最好的資料庫開發工具。各種各樣的控制項,功能強大的PowerBuilder語言都會幫助你開發出自己的資料庫應用程序。