8

追加の *.so ライブラリ (具体的には「libinterface.so」) を使用する Android アプリケーションを生成しようとしています。これらのライブラリは外部で生成され、Java 側から呼び出されるラッパー クラス内に依存関係として含まれます。ライブラリは「src/main/jniLibs/armeabi-v7a」に格納されています。システムは、生成されたアプリにすべての .so ファイルを含めます。

以前は、この目的で Eclipse を使用していて、このライブラリを使用できましたが、Android Studio でこれを行うには問題があります。

生成されたエラーは次のとおりです。

/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

リンカーによってエラーがスローされるため、ライブラリ インクルード ステップに関連しているように見えます。Eclipse では、「Android.mk」ファイルを使用して新しいライブラリをインクルードしていましたが、Gradle を使用してこれを行う方法が見つかりません。

#Android.mk
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE := libinterface-prebuilt
LOCAL_SRC_FILES := prebuilt/libinterface.so
include $(PREBUILT_SHARED_LIBRARY)

このgradle定義にライブラリを含めようとしています(注:このチュートリアルを使用して、最後のJNIサポートとgradle-experimentalを含めました):

...
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
}
...

ライブラリは、CMake および makefile ツールを使用して外部でコンパイルされ、Android プラットフォーム用に「正しく」クロスコンパイルされます (Eclipse および ADT でテスト済み)。

次のようにラッパーを実装しました。

// 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__

前もって感謝します。

アップデート:

この例に従って、いくつかのブロックを gradle スクリプトに含めました。

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.
4

1 に答える 1