2017-03-17 22 views
0

假設我們有一個預先構建的本地庫,名爲libname.a。 我們需要從Java活動中調用本地庫中包含的本地函數。一個例子是這樣的一個存儲在主頭文件:NDK - 包含預建庫並在Android項目中調用本地函數

DLLEXPORT int DLLCALL function(Xhandle handle, unsigned char *srcBuf, unsigned char *dstBuf); 

Xhandle是在頭文件還定義了一個結構體。

armv6 
|- header1.h 
|- header2.h 
|- ... 
|- libname.a 
armv7 
|- header1.h 
|- header2.h 
|- ... 
|- libname.a 
x86 
|- header1.h 
|- header2.h 
|- ... 
|- libname.a 

我們需要這個庫導入到我們的Android項目:

的文件如下,我們正在構建。 我們做了什麼:

  • 安裝了NDK和CMake工具。
  • Checked在創建項目時包含C++支持。
  • 在項目中創建一個jni目錄,並複製上述文件。

我們CMakeList.txt文件(存儲在項目的根文件夾):

cmake_minimum_required(VERSION 3.4.1) 

add_library(name 
      STATIC# We guessed it's a static due to the .a extension 
      IMPORTED # No source code (.c or .cpp) available) 

然後,我們創建了一個Android.mk文件中的JNI目錄:

LOCAL_PATH := $(call my-dir) 
TARGET_ARCH_ABI := armv7 

include $(CLEAR_VARS) 
LOCAL_MODULE := name 
LOCAL_SRC_FILES := $(TARGET_ARCH_ABI)/libname.a 
LOCAL_EXPORT_C_INCLUDES := $(TARGET_ARCH_ABI) 
include $(PREBUILT_STATIC_LIBRARY) 

所有這一切都從閱讀推導以下鏈接:

現在,我們知道我們需要添加這樣的事情:

public native int function(); 

// Used to load the 'native-lib' library on application startup. 
static { 
    System.loadLibrary("name"); 
} 

我們覺得我們做錯了什麼,而我們是遺漏了什麼。我們還必須定義這些論點,並且我們認爲我們應該寫一個包裝。

所以,任何幫助,將不勝感激。

+0

在包含原生函數定義的Java文件上運行'javah'。將會輸出正確的方法名稱的C頭文件。在C或C++文件中實現此方法,並在其中調用您的預構建函數。不要忘記將它們連接在一起。 –

+0

@RichardCritten「...包含原生函數定義的Java文件。」你的意思是Java的活動? –

+1

其中包含以下(或類似)行的Java文件:'public native int function();'此行告訴Java您有一個名爲'function'的本地方法,它不接受任何參數並返回一個int。 'javah'將從包,類和方法簽名中生成正確的C函數定義。 –

回答

0

在Java類中的功能本地方法的C++端需要

JNIEXPORT jstring JNICALL Java_my_package_name_MyClass_function(JNIEnv *env, jobject instance) 

。您的libname不提供此類導出的功能,因此您必須自己準備,因爲Richard Critten在註釋中進行了說明。你可以把你的包裝函數放在文件jniWrapper.cpp,旁邊的Android.mk。您的Android。MK可能看起來像

LOCAL_PATH := $(call my-dir) 

include $(CLEAR_VARS) 
LOCAL_MODULE := name 
LOCAL_SRC_FILES := $(TARGET_ARCH_ABI)/libname.a 
LOCAL_EXPORT_C_INCLUDES := $(LOCAL_PATH)/$(TARGET_ARCH_ABI) 
include $(PREBUILT_STATIC_LIBRARY) 

include $(CLEAR_VARS) 
LOCAL_MODULE := jniWrapper 
LOCAL_SRC_FILES := jniWrapper.cpp 
LOCAL_STATIC_LIBRARIES := name 
include $(BUILD_SHARD_LIBRARY) 

最後,lodalLibrary()不能加載靜態庫; Java類的靜態構造函數可能看起來像

static { 
    System.loadLibrary("jniWrapper"); 
} 
相關問題