當前位置:首頁 » 安卓系統 » android編譯jni

android編譯jni

發布時間: 2022-09-15 07:52:52

㈠ android studio JNI開發時 編譯成功 但是沒有生成.so文件 什麼原因

1
在交叉編譯的時候怎麼都無法生成so文件,javah生成頭文件沒錯,c文件也沒錯,java文件也沒錯,
2.原因:是JNI文件夾路徑不對
3
在執行javah命令時,我進入的是cd
app/src/main/java
這樣jni文件夾在java文件夾下,作為一個包存在,這樣就無法生成so文件
執行javah的正確姿勢:
4
進入app/src/main目錄:cd
app/src/main
執行javah命令:javah
javah
-d
jni
-classpath
./Java
lab.sodino.jnitest.MainActivity
5,
-d
jni
頭文件生成到jni文件夾(當前在<Project>\app\src\main目錄下,所以.h所在的目錄為<Project>\app\src\main\jni

-classpath
./java
指定去當前路徑下java下尋找包名指定的類
這樣再rebuild一下,就會生成so文件了

㈡ android studio 怎麼編譯jni

一、使用已經編譯好的so

這種情況比較件簡單,只要把的.so文件放到相應的目錄即可。如下:

.[mole_name]
. . [src]
. . .[main]
. . . .[jniLibs]
. . . . .[armeabi]
. . . . .[armeabi-v7a]
. . . . .[x86]
. . . . .[mips]

注意 jniLibs 目錄是放在 mole 下面,在Android Studio中效果如下,這樣編譯之後so就會被自動打包進apk,代碼中直接 loadLibrary即可了:

1 String libName = "helloNDK"; // 庫名, 注意沒有前綴lib和後綴.so
2 System.loadLibrary( libName );

二、使用C/C++源碼

1 r9d以上版本NDK

首先確保自己的NDK版本在r9d以上,目前最新可以拿到的是r10,下載地址:

http://tools.android-studio.org/

感謝 Android Studio中文組的無私奉獻。

如果低於r9d版本,Android studio 下ndk編譯會出現 No rule to make target 的錯誤。

2 配置 ndk.dir

在 local.properties 添加如下配置:

sdk.dir=/path/to/android-sdk

ndk.dir=/path/to/android-ndk

㈢ 如何在Android下使用JNI

關於如何在Android使用JNI調用C/C++代碼庫,網上已經有很多優秀的文章了,這里說一個大概過程吧:

首先需要懂C,其次要明白JNI的開發流程,然後還要知道NDK如何使用

1、在java代碼中聲明了一個native本地方法

Public native String helloFromc();

2、在項目目錄中創建JNI文件夾

3、在JNI文件夾裡面創建C文件,按照規范寫代碼

Jstring
Java_com_cheng_jnitest_MainActivity_helloFromc(JNIEnv* env,jobject obj)

4、用ndk-build指令編譯
編譯前需要配置Android.mk文件
//指定編譯的文件夾,指定當前的目錄
LOCAL_PATH := $(call my-dir)

//編譯器在編譯的時候會產生很多臨時變數,中間變數最好在編譯前清空所有的臨時變數

include $(CLEAR_VARS)

//編譯完成後的模塊名
LOCAL_MOUDLE := hello
//編譯的源文件

LOCAL_SRC_FILES:=hello.c

//編譯一個動態庫

//動態庫.so 只包含運行的函數,不包含依賴,所以體積小,運行的時候回去系統尋找依賴

//靜態庫.a 包含所有的函數和運行的依賴,所以體積大,包含所有的api

include $(BUILD_SHARED_LIBRARY)

5、生成了一個so動態庫,放到了libs裡面

6、項目中引入依賴庫

Static{

System.loadLibrary("hello");

}

㈣ android studio 編譯jni 跟工程有關嗎

1 在交叉編譯的時候怎麼都無法生成so文件,javah生成頭文件沒錯,c文件也沒錯,java文件也沒錯,
2.原因:是JNI文件夾路徑不對
3 在執行javah命令時,我進入的是cd app/src/main/java 這樣jni文件夾在java文件夾下,作為一個包存在,這樣就無法生成so文件
執行javah的正確姿勢:
4 進入app/src/main目錄:cd app/src/main
執行javah命令:javah

javah -d jni -classpath ./Java lab.sodino.jnitest.MainActivity

5, -d jni 頭文件生成到jni文件夾(當前在<Project>\app\src\main目錄下,所以.h所在的目錄為<Project>\app\src\main\jni )
-classpath ./java 指定去當前路徑下java下尋找包名指定的類
這樣再rebuild一下,就會生成so文件了

㈤ 如何在Android下使用JNI

第一步: 使用Java編寫HelloWorld 的Android應用程序: 復制代碼 package com.lucyfyr; import android.app.Activity; import android.os.Bundle; import android.util.Log; public class HelloWorld extends Activity { /** Called when the activity is first created. */ @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); Log.v("fresne", printJNI("I am HelloWorld Activity")); } static { //載入庫文件 System.loadLibrary("HelloWorldJni"); } //聲明原生函數 參數為String類型 返回類型為String private native String printJNI(String inputStr); } 復制代碼 這一步我們可以使用eclipse來生成一個App; 因為eclipse會自動為我們編譯此Java文件,後面要是用到。 第二步: 生成共享庫的頭文件: 進入到eclipse生成的Android Project中 :/HelloWorld/bin/classes/com/lucyfyr/ 下: 可以看到裡面後很多後綴為.class的文件,就是eclipse為我們自動編譯好了的java文件,其中就有: HelloWorld.class文件。 退回到classes一級目錄:/HelloWorld/bin/classes/ 執行如下命令: javah com.lucyfyr.HelloWorld 生成文件:com_lucyfyr_HelloWorld.h 復制代碼 /* DO NOT EDIT THIS FILE - it is machine generated */ #include <jni.h> /* Header for class com_lucyfyr_HelloWorld */ #ifndef _Included_com_lucyfyr_HelloWorld #define _Included_com_lucyfyr_HelloWorld #ifdef __cplusplus extern "C" { #endif /* * Class: com_lucyfyr_HelloWorld * Method: printJNI * Signature: (Ljava/lang/String;)Ljava/lang/String; */ JNIEXPORT jstring JNICALL Java_com_lucyfyr_HelloWorld_printJNI (JNIEnv *, jobject, jstring); #ifdef __cplusplus } #endif #endif 復制代碼 可以看到自動生成對應的函數:Java_com_lucyfyr_HelloWorld_printJNI Java_ + 包名(com.lucyfyr) + 類名(HelloWorld) + 介面名(printJNI):必須要按此JNI規范來操作; java虛擬機就可以在com.simon.HelloWorld類調用printJNI介面的時候自動找到這個C實現的Native函數調用。 當然函數名太長,可以在.c文件中通過函數名映射表來實現簡化。 第三步: 實現JNI原生函數源文件: 新建com_lucyfyr_HelloWorld.c文件: 復制代碼 #include <jni.h> #define LOG_TAG "HelloWorld" #include <utils/Log.h> /* Native interface, it will be call in java code */ JNIEXPORT jstring JNICALL Java_com_lucyfyr_HelloWorld_printJNI(JNIEnv *env, jobject obj,jstring inputStr) { LOGI("fresne Hello World From libhelloworld.so!"); // 從 instring 字元串取得指向字元串 UTF 編碼的指針 const char *str = (const char *)(*env)->GetStringUTFChars( env,inputStr, JNI_FALSE ); LOGI("fresne--->%s",(const char *)str); // 通知虛擬機本地代碼不再需要通過 str 訪問 Java 字元串。 (*env)->ReleaseStringUTFChars(env, inputStr, (const char *)str ); return (*env)->NewStringUTF(env, "Hello World! I am Native interface"); } /* This function will be call when the library first be load. * You can do some init in the libray. return which version jni it support. */ jint JNI_OnLoad(JavaVM* vm, void* reserved) { void *venv; LOGI("fresne----->JNI_OnLoad!"); if ((*vm)->GetEnv(vm, (void**)&venv, JNI_VERSION_1_4) != JNI_OK) { LOGE("fresne--->ERROR: GetEnv failed"); return -1; } return JNI_VERSION_1_4; } 復制代碼 OnLoadJava_com_lucyfyr_HelloWorld_printJNI 函數裡面做一些log輸出 注意JNI中的log輸出的不同。 JNI_OnLoad函數JNI規范定義的,當共享庫第一次被載入的時候會被回調, 這個函數裡面可以進行一些初始化工作,比如注冊函數映射表,緩存一些變數等, 最後返回當前環境所支持的JNI環境。本例只是簡單的返回當前JNI環境。 第四步: 編譯生成so庫 編譯com_lucyfyr_HelloWorld.c成so庫可以和app一起編譯,也可以都單獨編譯。 在當前目錄下建立jni文件夾:HelloWorld/jni/ 下建立Android.mk ,並將com_lucyfyr_HelloWorld.c和 com_lucyfyr_HelloWorld.h 拷貝到進去 編寫編譯生成so庫的Android.mk文件: 復制代碼 LOCAL_PATH:= $(call my-dir) # 一個完整模塊編譯 include $(CLEAR_VARS) LOCAL_SRC_FILES:=com_lucyfyr_HelloWorld.c LOCAL_C_INCLUDES := $(JNI_H_INCLUDE) LOCAL_MODULE := libHelloWorldJni LOCAL_SHARED_LIBRARIES := libutils LOCAL_PRELINK_MODULE := false LOCAL_MODULE_TAGS :=optional include $(BUILD_SHARED_LIBRARY) 復制代碼 系統變數解析: LOCAL_PATH - 編譯時的目錄 $(call 目錄,目錄….) 目錄引入操作符 如該目錄下有個文件夾名稱 src,則可以這樣寫 $(call src),那麼就會得到 src 目錄的完整路徑 include $(CLEAR_VARS) -清除之前的一些系統變數 LOCAL_MODULE - 編譯生成的目標對象 LOCAL_SRC_FILES - 編譯的源文件 LOCAL_C_INCLUDES - 需要包含的頭文件目錄 LOCAL_SHARED_LIBRARIES - 鏈接時需要的外部庫 LOCAL_PRELINK_MODULE - 是否需要prelink處理 include$(BUILD_SHARED_LIBRARY) - 指明要編譯成動態庫

㈥ Android用NDK和整套源碼下編譯JNI的不同

2. 注冊函數的方法是不同的。舉例說,在com/evan129/jnitest/jniutils.java有個native int foo()方法,需要在jni中實現
在ndk中,只要實現這個函數,然後函數名是以jint java_com_evan129_jnitest_jniutils_foo(jnienv* env, jobject thiz) 命名既可。也就是說,如果jni只要實現這個函數,並且功能也很簡單的話,那麼jni c/cpp文件里只需要這一個函數就完事了。
但在android源碼中編譯jni代碼是不同的,jni中的函數名無所謂。不過至少還需要加一個
jniexport jint jnicall jni_onload(javavm* vm, void* reserved)方法,這個方法可以找個現有的復制一把就行,檢查運行環境的。然後主要是這個方法中會調用(*env).registernatives函數,在這里把jni中的方法和java文件中的方法關聯起來。
3. 有個很詭異的區別,自動傳入的jnienv* env好像不是一個東西。因為在android源碼中使用這個env一般是如env->newstringutf(…),而ndk中sample里的一處是(*env)->newstringutf(…) 這env和*env差很大。但兩處函數傳入的都是jnienv* env,只能懷疑jnienv的定義是不是都是不同的。

㈦ android jni怎麼編譯

參考如下

打開Eclipse,選擇菜單 "File->New->other...";

選擇「Android->Android Project from Existing Code」後,點擊 Next;

① 點擊"Browse..."按鈕,選擇"ndk根目錄下->samples->hello-jni",如目錄是「D:\Android\android-ndk-r9d\samples\hello-jni」;
② 取消「Project:->Project to import->tests」的復選框;
③ 選中「Copy projects into workspace」
④ 然後點擊 Finish 完成

① 選擇「「HelloJni」工程後點擊右鍵->Android Tools->Add Native Support...」;
② 在 "Add Android Native Support" 界面點擊 Finish

打開工程文件 「hellojni->jni->hello-jni.c",發現報錯:」Method 'NewStringUTF' could not be resolved「;解決方法:
①將 文件名」hello-jni.c「改為」hello-jni.cpp「;
②將文件」hello-jni.cpp「中的
函數 」Java_com_example_hellojni_HelloJni_stringFromJNI「的最前面加上"extern C"
③將文件」hello-jni.cpp「中的
函數 」Java_com_example_hellojni_HelloJni_stringFromJNI「
的最後一行的代碼:
」return (*env)->NewStringUTF(env, "Hello from JNI ! Compiled with ABI " ABI ".");「
改為
」return env->NewStringUTF("Hello from JNI ! Compiled with ABI " ABI ".");「
④在工程文件"hellojni->jni->Android.mk」中的
「LOCAL_SRC_FILES := hello-jni.c」改為「LOCAL_SRC_FILES := hello-jni.cpp」
⑤點擊工具欄上的按鈕 Build All(Ctrl+B),或者使用快捷鍵"Ctrl+B"
⑥改為後的文件內容如下:

點擊工程"hellojni右鍵->Debug As->Andrid Native Application;結果報錯:
「Unable to resolve target 'android-3'」,解決方法:
打開工程文件「hellojni->AndroidManifest.xml」選擇」Manifest分頁->Manifest Extras->Uses SDK「,修改右邊」Atributes for User Sdk「下的「Min SDK Version」為19, 「Target SDK Version"為19, (註:19是android4.4.2版,目前最新版),保存;

保存後又發現錯誤提示」Avoid hardcoding the debug mode;「,解決方法:」打開AndroidManifest.xml文件Application分頁「,將"Application Attributes"下的 Debuggable 屬性框中的 true 清除掉;

點擊工程"hellojni右鍵->Debug As->Andrid Native Application;運行結構

㈧ Android用NDK和整套源碼下編譯JNI的不同

NDK:
1、包含頭文件
#include <android/log.h>
2、Android.mk中包含庫
LOCAL_LDLIBS += -L$(SYSROOT)/usr/lib -llog
上面這個一定要,不然出現error: undefined reference to '__android_log_print'
LOCAL_SHARED_LIBRARIES := libdl\
liblog\ #經測試在Eclipse中用NDK編譯可有可無,沒啥用!但在源碼中就必須是他,所以都加上吧!
libpre_AppUpgrade\
libpre_AppArea\
3、在你的jni文件中定義
#define LOGD() __android_log_print(ANDROID_LOG_DEBUG,LOG_TAG,__VA_ARGS__) // 定義LOGD類型
#define LOGI() __android_log_print(ANDROID_LOG_INFO,LOG_TAG,__VA_ARGS__) // 定義LOGI類型
#define LOGW() __android_log_print(ANDROID_LOG_WARN,LOG_TAG,__VA_ARGS__) // 定義LOGW類型
#define LOGE() __android_log_print(ANDROID_LOG_ERROR,LOG_TAG,__VA_ARGS__) // 定義LOGE類型
#define LOGF() __android_log_print(ANDROID_LOG_FATAL,LOG_TAG,__VA_ARGS__) // 定義LOGF類型
adnroid4.2源碼中已經將LOGD等都加了一個頭,
#define ALOGD() __android_log_print(ANDROID_LOG_DEBUG,LOG_TAG,__VA_ARGS__) // 定義LOGD類型
#define ALOGI() __android_log_print(ANDROID_LOG_INFO,LOG_TAG,__VA_ARGS__) // 定義LOGI類型
#define ALOGW() __android_log_print(ANDROID_LOG_WARN,LOG_TAG,__VA_ARGS__) // 定義LOGW類型
#define ALOGE() __android_log_print(ANDROID_LOG_ERROR,LOG_TAG,__VA_ARGS__) // 定義LOGE類型
#define ALOGF() __android_log_print(ANDROID_LOG_FATAL,LOG_TAG,__VA_ARGS__) // 定義LOGF類型
注意如果你不想在每一個jni文件中都定義上述宏,投機方法即可以定義在:D:\android-ndk-r9d\platforms\android-19\arch-arm\usr\include\android\log.h中!當然這種編譯也只能在你本機上使用啦~
源碼開發:
1、Android.mk中包含庫
LOCAL_LDLIBS += -L$(SYSROOT)/usr/lib -llog
LOCAL_SHARED_LIBRARIES := libdl\
liblog\ //源碼中開發一定的加上
libpre_AppUpgrade\
libpre_AppArea\
2、包含頭文件#include <utils/Log.h>
3、注意在使用時記得包含庫的頭文件
轉載

熱點內容
一級腳本號 發布:2025-01-10 14:08:06 瀏覽:531
知乎冷數據存儲 發布:2025-01-10 14:07:10 瀏覽:603
資料庫的列名 發布:2025-01-10 14:03:39 瀏覽:522
php安裝方法 發布:2025-01-10 13:53:51 瀏覽:606
linux網路文件夾共享 發布:2025-01-10 13:53:08 瀏覽:293
matlab編譯cpp 發布:2025-01-10 13:51:31 瀏覽:980
phppython混合編程 發布:2025-01-10 13:46:43 瀏覽:853
android轉圈 發布:2025-01-10 13:45:59 瀏覽:203
計算機等級考試資料庫 發布:2025-01-10 13:40:51 瀏覽:100
華為雙攝演算法 發布:2025-01-10 13:37:06 瀏覽:46