Windows下編譯使用Android NDK,呼叫SO檔案
阿新 • • 發佈:2019-02-02
下載後把壓縮包解壓出來,例如:D:\ndk,目錄下的ndk-build.cmd就是用來編譯的批處理命令。
這裡以D:\ndk\samples\hello-jni為例,開啟D:\ndk\samples\hello-jni\jni\hello-jni.c檢視程式碼:
因為我們是拿這個c原始碼檔案來使用,如果遷就Java_com_example_hellojni_HelloJni_stringFromJNI 函式名的話,在我們的android工程中java類的宣告就要是:com/example/hellojni/HelloJni.java。 反之,如果我們的android工程已經建立好,並且包名是com.example.hellojni,stringFromJNI函式我們寫在了MainActivity.java類裡, 那麼這裡的c函式就要修改為:Java_com_example_hellojni_MainActivity_stringFromJNI,否則在尋找函式時會找不到。 然後執行命令:D:\ndk\ndk-build.cmd(如果設定過環境變數則直接使用ndk-build.cmd)來編譯hello-jni,如果沒有錯誤會輸出: Gdbserver : [arm-linux-androideabi-4.6] libs/armeabi/gdbserver Gdbsetup : libs/armeabi/gdb.setup
"Compile thumb : hello-jni <= hello-jni.c
SharedLibrary : libhello-jni.so
Install : libhello-jni.so => libs/armeabi/libhello-jni.so
編譯成功會在D:\ndk\samples\hello-jni\libs\armeabi目錄下生成libhello-jni.so檔案。 三、建立android應用程式並使用so檔案 開啟eclipse建立一個android應用程式HelloJni,預設的com.example.hellojni包下面有一個MainActivity.java, 在此包下新增一個HelloJni.java,
MainActivity.java修改為:
把編譯生成的libhello-jni.so檔案複製到F:\eclipse_workspace\HelloJni\libs\armeabi目錄下(armeabi如果不存在則手動建立之),然後編譯執行,效果圖如下:
參考資料:
/* * Copyright (C) 2009 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. **/ #include <string.h> #include <jni.h> /* This is a trivial JNI example where we use a native method * to return a new VM String. See the corresponding Java source * file located at: * * apps/samples/hello-jni/project/src/com/example/hellojni/HelloJni.java */ jstring Java_com_example_hellojni_HelloJni_stringFromJNI( JNIEnv* env, jobject thiz ) { return(*env)->NewStringUTF(env, "Hello from JNI !"); }
因為我們是拿這個c原始碼檔案來使用,如果遷就Java_com_example_hellojni_HelloJni_stringFromJNI 函式名的話,在我們的android工程中java類的宣告就要是:com/example/hellojni/HelloJni.java。 反之,如果我們的android工程已經建立好,並且包名是com.example.hellojni,stringFromJNI函式我們寫在了MainActivity.java類裡, 那麼這裡的c函式就要修改為:Java_com_example_hellojni_MainActivity_stringFromJNI,否則在尋找函式時會找不到。 然後執行命令:D:\ndk\ndk-build.cmd(如果設定過環境變數則直接使用ndk-build.cmd)來編譯hello-jni,如果沒有錯誤會輸出: Gdbserver : [arm-linux-androideabi-4.6] libs/armeabi/gdbserver Gdbsetup : libs/armeabi/gdb.setup
"Compile thumb : hello-jni <= hello-jni.c
SharedLibrary : libhello-jni.so
Install : libhello-jni.so => libs/armeabi/libhello-jni.so
編譯成功會在D:\ndk\samples\hello-jni\libs\armeabi目錄下生成libhello-jni.so檔案。 三、建立android應用程式並使用so檔案 開啟eclipse建立一個android應用程式HelloJni,預設的com.example.hellojni包下面有一個MainActivity.java, 在此包下新增一個HelloJni.java,
package com.example.hellojni; public class HelloJni { public native String stringFromJNI(); /* This is another native method declaration that is *not* * implemented by 'hello-jni'. This is simply to show that * you can declare as many native methods in your Java code * as you want, their implementation is searched in the * currently loaded native libraries only the first time * you call them. * * Trying to call this function will result in a * java.lang.UnsatisfiedLinkError exception ! */ }
MainActivity.java修改為:
package com.example.hellojni; import android.os.Bundle; import android.app.Activity; import android.view.Menu; import android.widget.TextView; import android.util.Log; public class MainActivity extends Activity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); //setContentView(R.layout.activity_main); HelloJni jni = new HelloJni(); TextView tv = new TextView(this); String str = jni.stringFromJNI(); Log.d("HelloJni", str); tv.setText(str); setContentView(tv); } @Override public boolean onCreateOptionsMenu(Menu menu) { // Inflate the menu; this adds items to the action bar if it is present. getMenuInflater().inflate(R.menu.main, menu); return true; } static { System.loadLibrary("hello-jni"); } }
把編譯生成的libhello-jni.so檔案複製到F:\eclipse_workspace\HelloJni\libs\armeabi目錄下(armeabi如果不存在則手動建立之),然後編譯執行,效果圖如下:
參考資料: