【Android NDK】入門漂流記(二)-----踩坑出坑記(單.so文件生成和多.so文件生產,以及對CMakeLists.txt的探索)

 語言有的時候表述一件事真的很乏力,可能我理解的並沒有完全清楚的表達出來,如果你看到了,並且理解不了,那麼,就多琢磨吧

 

1、CMakeLists.txt篇(注意,這個文件的內容識別不區分大小寫的):

 

    1)設置輸出.so文件目錄設置:

 

 set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${PROJECT_SOURCE_DIR}/../outputJniLibs/${ANDROID_ABI})

        說明:
                PROJECT_SOURCE_DIR指的是當前CMakeLists.txt文件所在目錄,
                /..是上一級目錄的意思,
                ANDROID_ABI是指在app.build文件android -》defaultConfig -》externalNativeBuild -》cmake 下的abiFilters定義的一組目錄
        舉個栗子:
                如果當前CMakeLists.txt文件在app文件夾下,並且,那麼abiFilters值爲"x86","x86_64",那麼上面的設置就會把生  成的.so文件放在本項目的 頂級目錄 文件夾下的outputJniLibs中的x86文件夾和x86_64文件夾,不過實驗結果好像是,  運行到什麼架構的手機上就會在相應架構的文件夾下生成.so庫,其他的文件夾倒不會生成,不知原因爲何
    2)只生成一個.so文件的設置:

        (1)設置生成庫的源代碼:

  add_library(NativeHelper SHARED src/main/cpp/one/com_liuchaoya_c_NativeHelper.cpp)

            說明:這個方法有三個參數,分別以空格分割。
                NativeHelper  要生成的.so庫的名稱,
                SHARED 是否作爲共享庫,這個一般不用動,我是不會動,
                src/main/cpp/one/com_liuchaoya_c_NativeHelper.cpp  生成庫所需要的源文件


        (2)設置要鏈接的目標庫:target_link_libraries(NativeHelper ${log-lib}).
            說明:這個方法有兩個參數,分別以空格分割。
                NativeHelper  需要鏈接的目標庫,
                ${log-lib}  要鏈接的目標庫,這個log-lib庫是在NDK中定義好了的,直接鏈上,毫不猶豫


    3)生成多個.so文件的設置:
        (1)直接添加如下代碼(測試只生成兩個庫)
            ADD_SUBDIRECTORY(src/main/cpp/one)
            ADD_SUBDIRECTORY(src/main/cpp/two)

            對這裏的參數 路徑進行一下解釋:
                前提:這裏測試的源碼分別在app下的src/main/cpp/one和src/main/cpp/two文件夾中。

                說明:這個路徑仍然是跟着CMakeLists.txt文件的位置走的,當CMakeLists.txt文件在app下時,

   這個路徑就是src/main/cpp/*,      *代表目錄名,

                      當CMakeLists.txt在app的src/main/cpp下時,則可以直接這樣寫
                      ADD_SUBDIRECTORY(one)
                      ADD_SUBDIRECTORY(two)
                      就不用要前面的src/main/cpp/了

        (2)設置子目錄src/main/cpp/one和src/main/cpp/two下的CMakeLists.txt文件:
            src/main/cpp/one下:
                add_library(NativeHelper SHARED com_liuchaoya_c_NativeHelper.cpp)
                target_link_libraries(NativeHelper log)
                參數意義已經在上面的2)和3)中講過
            src/main/cpp/two下:
                add_library(NativeCHelper SHARED com_liuchaoya_c_NativeCHelper.c)
                target_link_libraries(NativeCHelper log)


            以上兩個文件內容的區別就是指定了庫的名稱和源文件路徑,僅此而已。


2、java調用工具類:
    1)不要忘了加載庫
        static {
            System.loadLibrary("庫名稱");
        }
    2)方法最好是靜態,方便調用

3、cpp源碼:
    1)需要將方法包括在
            extern "C"{...}  中,不然調用不到,會報沒有對應實現了的方法的錯誤
    2)方法名遵循 以下規則:Java_包名_工具類名_方法名
        例如:Java_com_liuchaoya_c_NativeHelper_getNativeString,這裏
            com_liuchaoya_c是包名(要加上工具類所在各級目錄名),
            NativeHelper是工具類名,
            getNativeString是方法名,
    3)返回值用法:
        以返回一個字符串爲例:
            cpp代碼 中是  return env->NewStringUTF("字符串");
            c代碼   中是  return (*env)->NewStringUTF(env, "字符串");
        注意區別


4、c源碼:
    1)不需要將方法包括在
                  extern "C"{...}  中,直接寫方法就行
       extern "C"的意思就是將包括的代碼以C語言進行處理編譯,而本身就是c的話就無需轉換


    2)其他同cpp基本相同,唯一一點返回值的區別在cpp中已經說過

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章