2012-09-26 243 views
2

我有一個java項目,現在我想添加一些NDK功能。Android-NDK編譯和鏈接

這裏是我的Android.mk

LOCAL_PATH := $(call my-dir) 

include $(CLEAR_VARS) 

LOCAL_MODULE := android 
LOCAL_CFLAGS := -Wno-psabi 
LOCAL_SRC_FILES := android.c 
LOCAL_LDLIBS := -L$(SYSROOT)/usr/lib -llog 

include $(BUILD_SHARED_LIBRARY) 

這裏是我的android.c

#include <jni.h> 
#include <string.h> 
#include <android/log.h> 

#define DEBUG_TAG "NDK_AndroidNDK1SampleActivity" 

void Java_ru_tonybo_app_NativeRenderer_print(JNIEnv* env, jobject thiz, jstring message) { 
    jboolean isCopy; 
    const char * szMessage = (*env)->GetStringUTFChars(env, message, &isCopy); 

    __android_log_print(ANDROID_LOG_DEBUG, DEBUG_TAG, "NDK:LC: [%s]", szMessage); 

    (*env)->ReleaseStringUTFChars(env, message, szMessage); 
} 

這裏是我相關的Java類

package ru.tonybo.app; 

public class NativeRenderer { 
    public NativeRenderer (String message) { 
     print(message); 
    } 

    public native void print(String message); 

    static { 
     System.loadLibrary("android"); 
    } 
} 

NDK編譯通過cygwin的是確定

[email protected] /cygdrive/d/javaProjects/App_JNI/jni 
$ /cygdrive/d/android-ndk-r8b/ndk-build -B 
Cygwin   : Generating dependency file converter script 
Compile thumb : android <= android.c 
SharedLibrary : libandroid.so 
Install  : libandroid.so => libs/armeabi/libandroid.so 

libandroid.so被創建並放置在/libs/armeabi/libandroid.so

,但是當我在Eclipse啓動設備上的應用程序,我得到異常UnsatisfiedLinkError對本地通話print(message);

我在這裏錯過或做錯了? 可能是我應該以某種方式告訴日食尋找共享庫,如果是的話如何做到這一點?

+0

我跑你的代碼輸出來了,你,爲了JNI的onload消息也有。 –

+0

這一切看起來不錯。 LogCat中有什麼有趣的東西?運行ARM-v7a/Intel/MIPS指令的設備是否有任何機會設置? –

+0

我正在使用三星galaxy tab2 http://browser.primatelabs.com/geekbench2/1084290 –

回答

3

您選擇的libandroid名稱不是一個好主意。存在於系統文件夾/system/lib中的庫libandroid.so。它被加載到您的應用程序中,因此您的Load()調用只是返回。如果你改變你的本地圖書館的名字,一切都會好的。

+0

是的,這是問題,但我看到這樣的命名在一個教程中,所以我認爲這是好的,但我錯了... –

+2

薑餅上出現'libandroid.so'。這就是爲什麼早期的例子可以使用這個名字。 –

1

您需要從共享庫中正確導出您的方法。使用方法聲明JNIEXPORTJNICALL宏:

JNIEXPORT void JNICALL Java_ru_tonybo_app_NativeRenderer_print(...) 
+0

我在此之前試過這個,但它沒有工作。所以它現在不工作...... 我在ndk軟件包的'hello-gl2'示例中看到了這個語法。但是'hello-jni'示例中沒有使用。這對我來說有點奇怪,你能解釋一下這個宏是什麼嗎? –

+1

這些宏在ARM的Android中幾乎沒有,但是它們是標準JNI約定的一部分。也就是說,'JNIEXPORT'確保函數在庫外部是「可見的」,即使其餘的函數是[hidden](http://gcc.gnu.org/wiki/Visibility)(很好的做法!) 。 'JNICALL'在Intel處理器上非常重要,您必須指定[** cdecl **](http://ervinloh.wordpress.com/2010/01/17/calling-conventions-cdecl-and-stdcall-cc/)而不是** stdcall **。 –

+0

謝謝,現在很清楚! –