最近使用AndroidStudio的最新ndk編譯方式cMake來編譯底層cpp文件,由於之前沒有接觸過cMake語法,先附上官方學習文檔地址:https://developer.android.com/ndk/guides/cmake.html,以及友情中文翻譯網址:https://www.zyb ...
最近使用AndroidStudio的最新ndk編譯方式cMake來編譯底層cpp文件,由於之前沒有接觸過cMake語法,先附上官方學習文檔地址:https://developer.android.com/ndk/guides/cmake.html,以及友情中文翻譯網址:https://www.zybuluo.com/khan-lau/note/254724;
底層c文件一大堆,如下圖所示
問題一:
其中native-lib.cpp是提供對外介面的,所以對其他文件的依賴都寫在了該文件中,接下來直接編譯嗎?no,那樣你會得到編譯錯誤,在native-lib.cpp中找不到其他c文件裡邊的函數。所以是cMake編譯的時候沒有把那些c文件編譯進去,這樣要去CMakeLists.txt中去添加文件了。
未修改之前的CMakeLists.txt文件內容是這樣的:
# Sets the minimum version of CMake required to build the native library. cmake_minimum_required(VERSION 3.4.1) # Creates and names a library, sets it as either STATIC # or SHARED, and provides the relative paths to its source code. # You can define multiple libraries, and CMake builds them for you. # Gradle automatically packages shared libraries with your APK. add_library( # Sets the name of the library. native-lib # Sets the library as a shared library. SHARED EXCLUDE_FROM_ALL # Provides a relative path to your source file(s). src/main/cpp/native-lib.cpp )
學習CMake的官方文檔可以知道,其中的add_library()正是設置生成包的地方,這裡只有native-lib.cpp一個文件,理論上應該要包括其他那些的,那麼加上其他那幾個文件就好了吧?是可以這樣,但是那麼多文件,未免也太長了吧,當然CMake肯定預料到這種問題了,所以我們可以get一個新技能,使用aux_source_directory(),在源文件位置添加文件列表,而不是單個文件,get修改之後的文件內容如下:
# Sets the minimum version of CMake required to build the native library. cmake_minimum_required(VERSION 3.4.1) # Creates and names a library, sets it as either STATIC # or SHARED, and provides the relative paths to its source code. # You can define multiple libraries, and CMake builds them for you. # Gradle automatically packages shared libraries with your APK. aux_source_directory(src/main/cpp SRC_LIST) add_library( # Sets the name of the library. native-lib # Sets the library as a shared library. SHARED EXCLUDE_FROM_ALL # Provides a relative path to your source file(s). #src/main/cpp/native-lib.cpp ${SRC_LIST} )
這樣子改完需要Synchronize同步一下,這樣就可以重新編譯了。
問題二:
在編譯通過之後,運行調用底層代碼,結果程式崩潰了,提示java.lang.UnsatisfiedLinkError: Native method not found: ***;好吧,沒有找到這個底層方法?可是明明已經生成了,仔細觀察上圖代碼結構可以發現,由於AndroidStudio自動生成的底層文件是.cpp的,也就是使用了c++的語法規則,而其他的底層文件都是.c的使用的c語言規則,他們兩者之間還是有區別的,現在需要在cpp文件中調用c文件,那麼要在cpp文件中做些修改,首先頭文件包含c的是相同的,不同點是在使用c文件中的函數上方,加一行 extern "C" 即可。這樣重新編譯運行,一切正常!