Android स्टूडियो और एनडीके पर अतिरिक्त*.so पुस्तकालयों का उपयोग कैसे करें
android-studio jni (1)
ठीक है, दो अलग-अलग समस्याएं हो सकती हैं
सबसे पहले, आपको यह सुनिश्चित करना होगा कि पुस्तकालय सही वास्तुकला के लिए संकलित है। यदि आप आर्मेबी-वी 7 ए लाइब्रेरी का उपयोग कर रहे हैं, लेकिन कंपाइलर अरमेबी पुस्तकालय को लोड करने का प्रयास कर रहा है, तो संकलन विफल हो जाएगा।
दूसरा, और पहले अंक के साथ भी, आपको प्रयुक्त वास्तुकला के आधार पर पुस्तकालयों को शामिल करना होगा। अपने मॉड्यूल build.gradle स्क्रिप्ट में ' स्वाद ' कॉन्फ़िगरेशन का उपयोग करें।
उदाहरण के लिए, आप ऐसा कुछ करने की कोशिश कर सकते हैं:
android.productFlavors {
create("arm") {
ndk.with{
abiFilters.add("armeabi")
File curDir = file('./')
curDir = file(curDir.absolutePath)
String libsDir = curDir.absolutePath + "/src/main/jniLibs/armeabi/"
ldLibs.add(libsDir + "libinterface.so")
}
}
create("armv7") {
ndk.with {
abiFilters.add("armeabi-v7a")
File curDir = file('./')
curDir = file(curDir.absolutePath)
String libsDir = curDir.absolutePath + "/src/main/jniLibs/armeabi-v7a/"
ldLibs.add(libsDir + "libinterface.so")
}
}
}
इसके अलावा, मैं आपको पुस्तकालयों को स्टोर करने के लिए 'jniLibs' का उपयोग करने का सुझाव देता हूं, क्योंकि यह उनके लिए डिफ़ॉल्ट पथ है, लेकिन प्रत्येक आर्क के लिए अलग-अलग फ़ोल्डर का उपयोग करें
आप इस तरह से अन्य उदाहरणों की जांच कर सकते हैं।
उम्मीद है की यह मदद करेगा। आदाब अर्ज है।
मैं कुछ अतिरिक्त * .so पुस्तकालयों (विशेष रूप से 'libinterface.so') का उपयोग करने के लिए एक एंड्रॉइड एप्लिकेशन बनाने की कोशिश कर रहा हूं। उन पुस्तकालयों को बाह्य रूप से तैयार किया जाता है, और जावा बाजू से आवरण वर्ग के अंदर निर्भरता के रूप में शामिल किया गया है। पुस्तकालय को 'src / main / jniLibs / armeabi-v7a' में जमा किया जाता है इस प्रणाली में सभी .so फ़ाइल को उत्पन्न ऐप में शामिल किया गया है।
पहले, मैं इस उद्देश्य के लिए एक्लिप्स का उपयोग कर रहा था और मैं इस पुस्तकालय का उपयोग करने में सक्षम था, लेकिन एंड्रॉइड स्टूडियो के साथ ऐसा करने में मुझे समस्या है
उत्पन्न त्रुटि है:
/home/******/Libraries/android-sdk-linux/ndk-bundle/toolchains/aarch64-linux-android-4.9/prebuilt/linux-x86_64/bin/../lib/gcc/aarch64-linux-android/4.9/../../../../aarch64-linux-android/bin/ld: cannot find -linterface
चूंकि लिंकर द्वारा त्रुटि डाली जाती है, यह पुस्तकालय शामिल करने के चरण से संबंधित दिखती है। ग्रहण पर, मैं एक नई लाइब्रेरी को शामिल करने के लिए एक 'एंड्रॉइड। एमक' फ़ाइल का उपयोग कर रहा था, लेकिन मैं इसे ग्रेडल का उपयोग करने का तरीका नहीं खोज सकता।
#Android.mk
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE := libinterface-prebuilt
LOCAL_SRC_FILES := prebuilt/libinterface.so
include $(PREBUILT_SHARED_LIBRARY)
मैं इस स्नातक परिभाषा के साथ पुस्तकालयों को शामिल करने की कोशिश कर रहा हूं (ध्यान दें: मैंने पिछले ट्यूटोरियल का उपयोग करके अंतिम जेएनआई समर्थन और स्नातक-प्रयोगात्मक शामिल किया है):
...
android.buildTypes {
release {
minifyEnabled = false
proguardFiles.add(file('proguard-android.txt'))
}
}
android.ndk {
moduleName = "custom_wrapper_jni"
cppFlags.add("-I" + file("src/main/jni").absolutePath)
cppFlags.add("-I" + file("../Integration/include").absolutePath) // <- New library header include path
cppFlags.add("-L" + file("src/main/jniLibs/armeabi-v7a").absolutePath) // <- Path where the library is stored
cppFlags.add("-std=c++11")
stl = "stlport_static" // Which STL library to use: gnustl or stlport
ldLibs.add("log")
ldLibs.add("interface") //<- Library to be included
}
...
लाइब्रेरी बाहरी रूप से सीमके और मेकफाइल टूल का उपयोग कर संकलित है, और यह एंड्रॉइड प्लेटफॉर्म (एल्प्से और एडीटी के साथ परीक्षण) के लिए 'सही तरीके से' संकलित है।
मैंने इस तरह आवरण को लागू किया है:
// custom_wrapper_jni.h
#ifndef ANDROID_JNI_H
#define ANDROID_JNI_H
#include <jni.h>
extern "C"
{
JNIEXPORT jint JNICALL
Java_com_example_goe_android_JniInterface_testFunction(JNIEnv *env,
jobject instance);
}
#endif
तथा
// custom_wrapper_jni.cpp
#include <custom_wrapper_jni.h>
#include "Interface.h" // Header of the included library
Interface* mInterface = Interface::create(); // Generate the library class instance
JNIEXPORT jint JNICALL
Java_com_example_goe_android_JniInterface_testFunction(JNIEnv *env,
jobject instance)
{
LOGI("Test function called in wrapper!");
return mInterface->test(); // Use the instance
}
लाइब्रेरी का शीर्षक इस तरह दिखता है:
#ifndef INTERFACE_H__
#define INTERFACE_H__
#include <string>
class Interface
{
public:
static Interface* create();
virtual ~Interface(){}
// Testing function
virtual int test() = 0;
protected:
Interface();
};
#endif // INTERFACE_H__
अग्रिम में धन्यवाद।
अद्यतन करें:
इस उदाहरण के बाद, मैंने कुछ ब्लॉक को स्लेप्ड में शामिल किया है:
def lib_path = file("src/main/jniLibs").absolutePath
model {
repositories {
libs(PrebuiltLibraries) {
newlibs {
headers.srcDir file("../Integration/include").absolutePath
binaries.withType(SharedLibraryBinary) {
sharedLibraryFile = file("${lib_path}/${targetPlatform.getName()}/libinterface.so")
println "Included libraries: " + file("${lib_path}/${targetPlatform.getName()}/libinterface.so")
}
}
}
}
android {
...
}
android.sources {
main {
jni {
dependencies {
library "newlibs" linkage "shared"
}
}
}
}
}
लेकिन काम नहीं कर रहा है:
Error: org.gradle.nativeplatform.toolchain.internal.CommandLineToolInvocationFailure: Linker failed while linking libcustom_wrapper_jni.so.