1. 程式人生 > >CMake再探:引入SO檔案並呼叫

CMake再探:引入SO檔案並呼叫

上次已經通過CMake編譯自己寫的C/C++程式碼了,這次嘗試匯入第三方程式碼來進行呼叫。通過上次寫的JniTest生成的so檔案來測試,生成的so檔案在專案的app/build/intermediates/cmake/debug/obj目錄下。


1.匯入so檔案

將so檔案拷貝到專案中,路徑自己定吧,只要配置的時候不出錯就行,我是這樣的拷貝到jniLibs資料夾中的。jniLibs下的子資料夾表示的是cpu型別,你可以少建些,但不可以不建,so檔案就放在這些資料夾下,每個cpu型別都放。

:匯入的so檔案需要在庫名前新增“lib”,即lib庫名.so,比如我要匯入庫名為test的so檔案,那麼你得將so檔名改為libtest.so再拷貝進專案)


2.配置

(1)在CMakeLists.txt中新增add_library()以及set_target_properties()方法


:通常情況下so檔案還會附帶.h標頭檔案(很明顯,我沒寫標頭檔案),這時候需要再加上include_directories()語句來定位標頭檔案的位置,不是很懂的童鞋可以去這裡看看

CMakeLists.txt:

# For more information about using CMake with Android Studio, read the
# documentation: https://d.android.com/studio/projects/add-native-code.html

# 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

             # Provides a relative path to your source file(s).
             src/main/cpp/native-lib.cpp )

add_library(test-lib SHARED IMPORTED)
set_target_properties(test-lib
  PROPERTIES IMPORTED_LOCATION
  ${CMAKE_SOURCE_DIR}/src/main/jniLibs/${ANDROID_ABI}/libtest-lib.so)

3.呼叫

匯入so檔案相當於你“實現”了方法,還需要“宣告”。比如我的so檔案中實現了“Java_com_example_win7_jnitest_util_JniUtil_stringFromSelf”方法,

com_example_win7_jnitest_util”表示的是包名,

JniUtil”表示的是方法所在類,“stringFromSelf”表示的是方法名。

因此,我在“com.example.win7.jnitest.util”包下新建了JniUtil類來聲名方法

:so檔案實現了哪些方法可以在.h標頭檔案中看到)

JniUtil.java:

public class 
JniUtil { static { System.loadLibrary("test-lib"); } public static native String stringFromSelf(String str); //這裡雖然是紅字,但可以跑起來 }
在MainActivity中呼叫該方法:
public class MainActivity extends AppCompatActivity {

    @Override
protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
// Example of a call to a native method
TextView tv = (TextView) findViewById(R.id.sample_text);
tv.setText(JniUtil.stringFromSelf("jack"));
}

}

附Demo下載地址