Android NDK - ข้อผิดพลาดในการสร้าง Gradle

ฉันรวบรวมไลบรารี SoundTouch สำเร็จแล้วและคัดลอกไฟล์ผลลัพธ์ลงในโฟลเดอร์ libs ของโปรเจ็กต์ของฉัน

ห้องสมุด

ภายในแต่ละโฟลเดอร์นี้จะมีไฟล์ libsoundtouch.so

ในโฟลเดอร์ jni ของโครงการของฉัน ฉันมีไฟล์ต่อไปนี้:

  • Android.mk
  • Application.mk
  • soundtouch-jni.cpp

Android.mk ของฉันมีลักษณะดังนี้:

LOCAL_PATH := $(call my-dir)

include $(CLEAR_VARS)

# *** Remember: Change -O0 into -O2 in add-applications.mk ***

LOCAL_MODULE    := soundtouch
LOCAL_SRC_FILES := soundtouch-jni.cpp ../../SoundTouch/AAFilter.cpp  ../../SoundTouch/FIFOSampleBuffer.cpp \
                ../../SoundTouch/FIRFilter.cpp ../../SoundTouch/cpu_detect_x86.cpp \
                ../../SoundTouch/sse_optimized.cpp ../../SoundStretch/WavFile.cpp \
                ../../SoundTouch/RateTransposer.cpp ../../SoundTouch/SoundTouch.cpp \
                ../../SoundTouch/InterpolateCubic.cpp ../../SoundTouch/InterpolateLinear.cpp \
                ../../SoundTouch/InterpolateShannon.cpp ../../SoundTouch/TDStretch.cpp \
                ../../SoundTouch/BPMDetect.cpp ../../SoundTouch/PeakFinder.cpp 

# for native audio
LOCAL_SHARED_LIBRARIES += -lgcc 
# --whole-archive -lgcc 
# for logging
LOCAL_LDLIBS    += -llog
# for native asset manager
#LOCAL_LDLIBS    += -landroid

# Custom Flags: 
# -fvisibility=hidden : don't export all symbols
LOCAL_CFLAGS += -fvisibility=hidden -I ../../../include -fdata-sections -ffunction-sections

# OpenMP mode : enable these flags to enable using OpenMP for parallel computation 
#LOCAL_CFLAGS += -fopenmp
#LOCAL_LDFLAGS += -fopenmp


# Use ARM instruction set instead of Thumb for improved calculation performance in ARM CPUs 
LOCAL_ARM_MODE := arm

include $(BUILD_SHARED_LIBRARY)

และนี่คือไฟล์ module build.gradle ของฉัน:

apply plugin: 'com.android.application'

android {
    signingConfigs {
        dev_key {
            keyAlias '#########'
            keyPassword '########'
            storeFile file('/Users/daniele/Desktop/Chords/########')
            storePassword '#######'
        }
    }
    compileSdkVersion 26
    buildToolsVersion "26.0.1"
    defaultConfig {
        applicationId "com.dancam.chords"
        minSdkVersion 21
        targetSdkVersion 26
        versionCode 16
        versionName "2.1"
        signingConfig ##########
        multiDexEnabled true
    }
    buildTypes {
        release {
            shrinkResources true
            minifyEnabled true
            proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
        }
    }
    productFlavors {
    }

    dataBinding {
        enabled = true
    }
}

dependencies {
    compile fileTree(include: ['*.jar'], dir: 'libs')
    androidTestCompile('com.android.support.test.espresso:espresso-core:2.2.2', {
        exclude group: 'com.android.support', module: 'support-annotations'
    })

ฉันนำเข้าฟังก์ชันดั้งเดิม:

public final class SoundTouch {
    public native final static String getVersionString();

// Load the native library upon startup
static
{
    System.loadLibrary("soundtouch");
}
}

นี่คือไฟล์ soundtouch-jni.cpp ของฉัน:

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

using namespace std;

#include "../../../include/SoundTouch.h"
#include "../source/SoundStretch/WavFile.h"

#define LOGV(...)   __android_log_print((int)ANDROID_LOG_INFO, "SOUNDTOUCH", __VA_ARGS__)
//#define LOGV(...)


// String for keeping possible c++ exception error messages. Notice that this isn't
// thread-safe but it's expected that exceptions are special situations that won't
// occur in several threads in parallel.
static string _errMsg = "";


#define DLL_PUBLIC __attribute__ ((visibility ("default")))
#define BUFF_SIZE 4096


using namespace soundtouch;


// Set error message to return
static void _setErrmsg(const char *msg)
{
    _errMsg = msg;
}


#ifdef _OPENMP

#include <pthread.h>
extern pthread_key_t gomp_tls_key;
static void * _p_gomp_tls = NULL;

/// Function to initialize threading for OpenMP.
///
/// This is a workaround for bug in Android NDK v10 regarding OpenMP: OpenMP works only if
/// called from the Android App main thread because in the main thread the gomp_tls storage is
/// properly set, however, Android does not properly initialize gomp_tls storage for other threads.
/// Thus if OpenMP routines are invoked from some other thread than the main thread,
/// the OpenMP routine will crash the application due to NULL pointer access on uninitialized storage.
///
/// This workaround stores the gomp_tls storage from main thread, and copies to other threads.
/// In order this to work, the Application main thread needws to call at least "getVersionString"
/// routine.
static int _init_threading(bool warn)
{
    void *ptr = pthread_getspecific(gomp_tls_key);
    LOGV("JNI thread-specific TLS storage %ld", (long)ptr);
    if (ptr == NULL)
    {
        LOGV("JNI set missing TLS storage to %ld", (long)_p_gomp_tls);
        pthread_setspecific(gomp_tls_key, _p_gomp_tls);
    }
    else
    {
        LOGV("JNI store this TLS storage");
        _p_gomp_tls = ptr;
    }
    // Where critical, show warning if storage still not properly initialized
    if ((warn) && (_p_gomp_tls == NULL))
    {
        _setErrmsg("Error - OpenMP threading not properly initialized: Call SoundTouch.getVersionString() from the App main thread!");
        return -1;
    }
    return 0;
}

#else
static int _init_threading(bool warn)
{
    // do nothing if not OpenMP build
    return 0;
}
#endif


// Processes the sound file
static void _processFile(SoundTouch *pSoundTouch, const char *inFileName, const char *outFileName)
{
    int nSamples;
    int nChannels;
    int buffSizeSamples;
    SAMPLETYPE sampleBuffer[BUFF_SIZE];

    // open input file
    WavInFile inFile(inFileName);
    int sampleRate = inFile.getSampleRate();
    int bits = inFile.getNumBits();
    nChannels = inFile.getNumChannels();

    // create output file
    WavOutFile outFile(outFileName, sampleRate, bits, nChannels);

    pSoundTouch->setSampleRate(sampleRate);
    pSoundTouch->setChannels(nChannels);

    assert(nChannels > 0);
    buffSizeSamples = BUFF_SIZE / nChannels;

    // Process samples read from the input file
    while (inFile.eof() == 0)
    {
        int num;

        // Read a chunk of samples from the input file
        num = inFile.read(sampleBuffer, BUFF_SIZE);
        nSamples = num / nChannels;

        // Feed the samples into SoundTouch processor
        pSoundTouch->putSamples(sampleBuffer, nSamples);

        // Read ready samples from SoundTouch processor & write them output file.
        // NOTES:
        // - 'receiveSamples' doesn't necessarily return any samples at all
        //   during some rounds!
        // - On the other hand, during some round 'receiveSamples' may have more
        //   ready samples than would fit into 'sampleBuffer', and for this reason
        //   the 'receiveSamples' call is iterated for as many times as it
        //   outputs samples.
        do
        {
            nSamples = pSoundTouch->receiveSamples(sampleBuffer, buffSizeSamples);
            outFile.write(sampleBuffer, nSamples * nChannels);
        } while (nSamples != 0);
    }

    // Now the input file is processed, yet 'flush' few last samples that are
    // hiding in the SoundTouch's internal processing pipeline.
    pSoundTouch->flush();
    do
    {
        nSamples = pSoundTouch->receiveSamples(sampleBuffer, buffSizeSamples);
        outFile.write(sampleBuffer, nSamples * nChannels);
    } while (nSamples != 0);
}



extern "C" DLL_PUBLIC jstring Java_net_surina_soundtouch_SoundTouch_getVersionString(JNIEnv *env, jobject thiz)
{
    const char *verStr;

    LOGV("JNI call SoundTouch.getVersionString");

    // Call example SoundTouch routine
    verStr = SoundTouch::getVersionString();

    /// gomp_tls storage bug workaround - see comments in _init_threading() function!
    _init_threading(false);

    int threads = 0;
    #pragma omp parallel
    {
        #pragma omp atomic
        threads ++;
    }
    LOGV("JNI thread count %d", threads);

    // return version as string
    return env->NewStringUTF(verStr);
}



extern "C" DLL_PUBLIC jlong Java_net_surina_soundtouch_SoundTouch_newInstance(JNIEnv *env, jobject thiz)
{
    return (jlong)(new SoundTouch());
}


extern "C" DLL_PUBLIC void Java_net_surina_soundtouch_SoundTouch_deleteInstance(JNIEnv *env, jobject thiz, jlong handle)
{
    SoundTouch *ptr = (SoundTouch*)handle;
    delete ptr;
}


extern "C" DLL_PUBLIC void Java_net_surina_soundtouch_SoundTouch_setTempo(JNIEnv *env, jobject thiz, jlong handle, jfloat tempo)
{
    SoundTouch *ptr = (SoundTouch*)handle;
    ptr->setTempo(tempo);
}


extern "C" DLL_PUBLIC void Java_net_surina_soundtouch_SoundTouch_setPitchSemiTones(JNIEnv *env, jobject thiz, jlong handle, jfloat pitch)
{
    SoundTouch *ptr = (SoundTouch*)handle;
    ptr->setPitchSemiTones(pitch);
}


extern "C" DLL_PUBLIC void Java_net_surina_soundtouch_SoundTouch_setSpeed(JNIEnv *env, jobject thiz, jlong handle, jfloat speed)
{
    SoundTouch *ptr = (SoundTouch*)handle;
    ptr->setRate(speed);
}


extern "C" DLL_PUBLIC jstring Java_net_surina_soundtouch_SoundTouch_getErrorString(JNIEnv *env, jobject thiz)
{
    jstring result = env->NewStringUTF(_errMsg.c_str());
    _errMsg.clear();

    return result;
}


extern "C" DLL_PUBLIC int Java_net_surina_soundtouch_SoundTouch_processFile(JNIEnv *env, jobject thiz, jlong handle, jstring jinputFile, jstring joutputFile)
{
    SoundTouch *ptr = (SoundTouch*)handle;

    const char *inputFile = env->GetStringUTFChars(jinputFile, 0);
    const char *outputFile = env->GetStringUTFChars(joutputFile, 0);

    LOGV("JNI process file %s", inputFile);

    /// gomp_tls storage bug workaround - see comments in _init_threading() function!
    if (_init_threading(true)) return -1;

    try
    {
        _processFile(ptr, inputFile, outputFile);
    }
    catch (const runtime_error &e)
    {
        const char *err = e.what();
        // An exception occurred during processing, return the error message
        LOGV("JNI exception in SoundTouch::processFile: %s", err);
        _setErrmsg(err);
        return -1;
    }


    env->ReleaseStringUTFChars(jinputFile, inputFile);
    env->ReleaseStringUTFChars(joutputFile, outputFile);

    return 0;
}

แก้ไข:

หลังจากทำตามที่ Alex Cohn แนะนำ ฉันพบข้อผิดพลาดต่อไปนี้:

คำสั่ง Build ล้มเหลว

Error while executing process /Users/daniele/Library/Android/sdk/ndk-bundle/ndk-build with arguments {NDK_PROJECT_PATH=null APP_BUILD_SCRIPT=/Users/daniele/Developer/AndroidProjects/Chords2/app/jni/Android.mk NDK_APPLICATION_MK=/Users/daniele/Developer/AndroidProjects/Chords2/app/jni/Application.mk APP_ABI=armeabi-v7a NDK_ALL_ABIS=armeabi-v7a NDK_DEBUG=0 APP_PLATFORM=android-21 NDK_OUT=/Users/daniele/Developer/AndroidProjects/Chords2/app/build/intermediates/ndkBuild/release/obj NDK_LIBS_OUT=/Users/daniele/Developer/AndroidProjects/Chords2/app/build/intermediates/ndkBuild/release/lib APP_SHORT_COMMANDS=false LOCAL_SHORT_COMMANDS=false -B -n}
rm -f /Users/daniele/Developer/AndroidProjects/Chords2/app/build/intermediates/ndkBuild/release/lib/armeabi-v7a/*
rm -f /Users/daniele/Developer/AndroidProjects/Chords2/app/build/intermediates/ndkBuild/release/lib/armeabi-v7a/gdbserver
rm -f /Users/daniele/Developer/AndroidProjects/Chords2/app/build/intermediates/ndkBuild/release/lib/armeabi-v7a/gdb.setup
mkdir -p /Users/daniele/Developer/AndroidProjects/Chords2/app/build/intermediates/ndkBuild/release/obj/local/armeabi-v7a/objs/soundtouch
echo [armeabi-v7a] "Compile++ arm  ": "soundtouch <= soundtouch-jni.cpp"
/Users/daniele/Library/Android/sdk/ndk-bundle/toolchains/llvm/prebuilt/darwin-x86_64/bin/clang++ -MMD -MP -MF /Users/daniele/Developer/AndroidProjects/Chords2/app/build/intermediates/ndkBuild/release/obj/local/armeabi-v7a/objs/soundtouch/soundtouch-jni.o.d -gcc-toolchain /Users/daniele/Library/Android/sdk/ndk-bundle/toolchains/arm-linux-androideabi-4.9/prebuilt/darwin-x86_64 -fpic -ffunction-sections -funwind-tables -fstack-protector-strong -Wno-invalid-command-line-argument -Wno-unused-command-line-argument -no-canonical-prefixes -fno-integrated-as -g -target armv7-none-linux-androideabi -march=armv7-a -mfloat-abi=softfp -mfpu=vfpv3-d16 -fno-exceptions -fno-rtti -marm -O2 -DNDEBUG  -I/Users/daniele/Library/Android/sdk/ndk-bundle/sources/cxx-stl/stlport/stlport -I/Users/daniele/Library/Android/sdk/ndk-bundle/sources/cxx-stl//gabi++/include -I/Users/daniele/Developer/AndroidProjects/Chords2/app/jni -DANDROID -fvisibility=hidden -I ../../../include -fdata-sections -ffunction-sections -Wa,--noexecstack -Wformat -Werror=format-security  -frtti   -fexceptions  -isystem /Users/daniele/Library/Android/sdk/ndk-mbundake: *** No rule to make target `/Users/daniele/Delveeloper/platforms/android-/AndroidProjects/Chords2/app/jni/../../SoundTouch/AAFilter.cpp', needed by `/Users/daniele/Developer/AndroidProjects/Chords2/app/build/intermedi2ates/ndkBuild/1/arch-arm/usr/include -c release/obj/local/armeabi-v7a/objs/soun /Users/dtdaniele/Douch/__/__/SoeveloundTouch/AAFpilter.o'.  Stop.
er/AndroidProjects/Chords2/app/jni/soundtouch-jni.cpp -o /Users/daniele/Developer/AndroidProjects/Chords2/app/build/intermediates/ndkBuild/release/obj/local/armeabi-v7a/objs/soundtouch/soundtouch-jni.o 

คำสั่ง Build ล้มเหลว

Error while executing process /Users/daniele/Library/Android/sdk/ndk-bundle/ndk-build with arguments {NDK_PROJECT_PATH=null APP_BUILD_SCRIPT=/Users/daniele/Developer/AndroidProjects/Chords2/app/jni/Android.mk NDK_APPLICATION_MK=/Users/daniele/Developer/AndroidProjects/Chords2/app/jni/Application.mk APP_ABI=armeabi-v7a NDK_ALL_ABIS=armeabi-v7a NDK_DEBUG=1 APP_PLATFORM=android-21 NDK_OUT=/Users/daniele/Developer/AndroidProjects/Chords2/app/build/intermediates/ndkBuild/debug/obj NDK_LIBS_OUT=/Users/daniele/Developer/AndroidProjects/Chords2/app/build/intermediates/ndkBuild/debug/lib APP_SHORT_COMMANDS=false LOCAL_SHORT_COMMANDS=false -B -n}
rm -f /Users/daniele/Developer/AndroidProjects/Chords2/app/build/intermediates/ndkBuild/debug/lib/armeabi-v7a/*
rm -f /Users/daniele/Developer/AndroidProjects/Chords2/app/build/intermediates/ndkBuild/debug/lib/armeabi-v7a/gdbserver
rm -f /Users/daniele/Developer/AndroidProjects/Chords2/app/build/intermediates/ndkBuild/debug/lib/armeabi-v7a/gdb.setup
mkdir -p /Users/daniele/Developer/AndroidProjects/Chords2/app/build/intermediates/ndkBuild/debug/lib/armeabi-v7a
echo [armeabi-v7a] "Gdbserver      ": "[arm-linux-androideabi] /Users/daniele/Developer/AndroidProjects/Chords2/app/build/intermediates/ndkBuild/debug/lib/armeabi-v7a/gdbserver"
install -p /Users/daniele/Library/Android/sdk/ndk-bundle/prebuilt/android-arm/gdbserver/gdbserver /Users/daniele/Developer/AndroidProjects/Chords2/app/build/intermediates/ndkBuild/debug/lib/armeabi-v7a/gdbserver
echo [armeabi-v7a] "Gdbsetup       ": "/Users/daniele/Developer/AndroidProjects/Chords2/app/build/intermediates/ndkBuild/debug/lib/armeabi-v7a/gdb.setup"
echo "set solib-search-path /Users/daniele/Developer/AndroidProjects/Chords2/app/build/intermediates/ndkBuild/debug/obj/local/armeabi-v7a" > /Users/daniele/Developer/AndroidProjects/Chords2/app/build/intermediates/ndkBuild/debug/lib/armeabi-v7a/gdb.setup
echo "directory /Users/daniele/Library/Android/sdk/ndk-bundle/platforms/android-21/arch-arm/usr/include /Users/daniele/Library/Android/sdk/ndk-bundle/sources/cxx-stl/stlport/stlport /Users/daniele/Library/Android/sdk/ndk-bundle/sources/cxx-stl//gabi++/include /Users/daniele/Developer/AndroidProjects/Chords2/app/jni" >> /Users/daniele/Developer/AndroidProjects/Chords2/app/build/intermediates/ndkBuild/debug/lib/armeabi-v7a/gdb.setup
mkdir -p /Users/daniele/Developer/AndroidProjects/Chords2/app/build/intermediates/ndkBuild/debug/obj/local/armeabi-v7a/objs/soundtouch
echo [armeabi-v7a] "Compile++ arm  ": "soundtouch <= soundtouch-jni.cpp"
/Users/daniele/Library/Android/sdk/ndk-bundle/toolchains/llvm/prebuilt/darwin-x86_64/bin/clang++ -MMD -MP -MF /Users/daniele/Developer/Androidmake: *** No rule to make target `/Users/daniele/Developer/AndroidProjects/Chords2/app/jniPro/../../SojeundTouch/AAFilter.cpp'c, ts/nCheeded by `o/Usrdsers/daniele/Develo2/apper/AndroidpProjects/Chords2/app/build/intermediates/ndkBuild//bdebug/obj/local/uiarmeabi-v7a/objs/soundtouch/__/__/SoundldTouch/AAFilter.o'.  Stop.
/intermediates/ndkBuild/debug/obj/local/armeabi-v7a/objs/soundtouch/soundtouch-jni.o.d -gcc-toolchain /Users/daniele/Library/Android/sdk/ndk-bundle/toolchains/arm-linux-androideabi-4.9/prebuilt/darwin-x86_64 -fpic -ffunction-sections -funwind-tables -fstack-protector-strong -Wno-invalid-command-line-argument -Wno-unused-command-line-argument -no-canonical-prefixes -fno-integrated-as -g -target armv7-none-linux-androideabi -march=armv7-a -mfloat-abi=softfp -mfpu=vfpv3-d16 -fno-exceptions -fno-rtti -marm -O2 -DNDEBUG  -I/Users/daniele/Library/Android/sdk/ndk-bundle/sources/cxx-stl/stlport/stlport -I/Users/daniele/Library/Android/sdk/ndk-bundle/sources/cxx-stl//gabi++/include -I/Users/daniele/Developer/AndroidProjects/Chords2/app/jni -DANDROID -fvisibility=hidden -I ../../../include -fdata-sections -ffunction-sections -Wa,--noexecstack -Wformat -Werror=format-security  -frtti   -fexceptions  -isystem /Users/daniele/Library/Android/sdk/ndk-bundle/platforms/android-21/arch-arm/usr/include -c  /Users/daniele/Developer/AndroidProjects/Chords2/app/jni/soundtouch-jni.cpp -o /Users/daniele/Developer/AndroidProjects/Chords2/app/build/intermediates/ndkBuild/debug/obj/local/armeabi-v7a/objs/soundtouch/soundtouch-jni.o

โปรดทราบ: ฉันรวบรวม Soundtouch Library โดยใช้ ndk-build บน Ubuntu Linux จากนั้นคัดลอกไปยัง macOS ที่ฉันทำงานตามปกติ

เบาะแสใด ๆ เกี่ยวกับวิธีแก้ไขปัญหานี้


person Daniele    schedule 05.09.2017    source แหล่งที่มา
comment
โปรดรวมไฟล์ส่วนหัวที่ส่งออกฟังก์ชัน C ดั้งเดิมด้วย และบันทึกข้อผิดพลาด (logcat) รอบข้อผิดพลาด (มีข้อความพิเศษที่จะช่วยวินิจฉัยปัญหา)   -  person Richard Critten    schedule 05.09.2017
comment
@RichardCritten คุณหมายถึง soundtouuch-jni.cpp ใช่ไหม   -  person Daniele    schedule 05.09.2017
comment
ฉันต้องการดูคำประกาศ C ฉบับเต็มของ getVersionString   -  person Richard Critten    schedule 05.09.2017
comment
ฉันไม่รู้ว่าจะหาฟังก์ชัน getVersionString ได้ที่ไหน อย่างไรก็ตามฟังก์ชันทั้งหมดทำให้เกิดข้อผิดพลาด   -  person Daniele    schedule 05.09.2017
comment
ส่วนใหญ่เหมือนกับคอมไพเลอร์/ตัวเชื่อมโยงได้ส่งออกสัญลักษณ์ใน libsoundtouch ด้วยชื่อที่ไม่เป็นระเบียบ ใช้ nm เพื่อดูว่าจริงๆ แล้วชื่อของฟังก์ชันที่โมดูลส่งออกคืออะไร ด้านที่น่าหงุดหงิดฉาวโฉ่ของ JNI คุณอาจมีการส่งออกชื่อที่ไม่เสียหายได้โดยใช้ extern C {}   -  person JJF    schedule 05.09.2017
comment
@JJF ฉันจะพยายามสร้างมันใหม่   -  person Daniele    schedule 05.09.2017
comment
ฉันคิดว่าคุณมีงานต้องทำมากกว่านี้ จากสิ่งที่ฉันบอกได้ว่าไลบรารีที่คุณพยายามใช้ไม่รองรับรูปแบบการเรียก C (ซึ่งเป็นสิ่งที่ JNI ต้องการ) ดังนั้นคุณจะต้องเขียนบริดจ์ใน C ที่ JVM เรียกซึ่งจะเรียก CPP ในทางกลับกัน รหัส. ดู github.com/bytedeco/javacpp เพื่อดูว่าคุณกำลังเผชิญอะไรอยู่   -  person JJF    schedule 05.09.2017
comment
@JJF คุณช่วยดูซอร์สโค้ดได้ไหม? มีตัวอย่าง Android ที่ใช้งานได้ บางทีคุณอาจได้รับข้อมูลเพิ่มเติมจากที่นั่น ฉันรวบรวมและสร้างมันตามคำแนะนำใน README นี่คือลิงก์ซอร์สโค้ด: surina.net/soundtouch/sourcecode.html   -  person Daniele    schedule 05.09.2017
comment
คลาส SoundTouch ของคุณอยู่ในแพ็คเกจใด ตัวอย่างนั้นจะต้องมีคลาส SoundTouch อยู่ในแพ็คเกจ net.surina.soundtouch ชื่อแพ็กเกจเป็นส่วนหนึ่งของชื่อฟังก์ชัน JNI   -  person JJF    schedule 05.09.2017
comment
และ soundtouch-jni.cpp นั้นก็มีชื่อที่ไม่ซับซ้อนให้คุณใช้ เช่น. ภายนอก C DLL_PUBLIC jstring Java_net_surina_soundtouch_SoundTouch_getVersionString (JNIEnv * env, jobject thiz); หมายเหตุชื่อแพ็กเกจที่รวมอยู่ในชื่อฟังก์ชัน   -  person JJF    schedule 05.09.2017
comment
@JFF ฉันเห็นว่ามันเป็นเรื่องจริงที่ฉันมีชื่อฟังก์ชั่นที่ไม่ซับซ้อน เป็นเพราะข้อผิดพลาดระหว่างการคอมไพล์หรือไม่?   -  person Daniele    schedule 06.09.2017
comment
@JFF ฉันเพิ่ม soundtouuch-jni.cpp ในคำถามเพื่อให้คุณได้ดู   -  person Daniele    schedule 06.09.2017
comment
คนที่ลงคะแนนในใจจะอธิบายว่าทำไม?   -  person Daniele    schedule 06.09.2017
comment
มีคำตอบมากมายที่กล่าวถึงข้อความแสดงข้อผิดพลาด 'ไม่สามารถแก้ไขฟังก์ชัน JNI ที่สอดคล้องกันได้' โปรดพิจารณาสิ่งนี้ด้วย: stackoverflow.com/a/44225181/192373 TL; NR: Android Studio จะไม่ค้นหาไฟล์ .so ของคุณสำหรับวิธีการดั้งเดิม แต่จะค้นหาได้เฉพาะเมื่อคุณใช้ externalNativeBuild ที่ผสานรวมเท่านั้น   -  person Alex Cohn    schedule 06.09.2017
comment
@AlexCohn ฉันเข้าใจแล้ว ดังนั้นข้อผิดพลาดนั้นควรเกี่ยวข้องกับ Android Studio และควรจะไม่เป็นไรเมื่อฉันเรียกใช้ apk ฉันควรเพิกเฉยต่อมันไหม? โปรดบอกฉันเพิ่มเติมเกี่ยวกับ externalNativeBuild สิ่งนี้ ฉันจะนำไปใช้ได้อย่างไร มันจะอนุญาตให้ Android Studio แก้ไขฟังก์ชั่น jni เหล่านั้นหรือไม่?   -  person Daniele    schedule 07.09.2017
comment
@AlexCohn ตามที่คุณแนะนำที่นี่: stackoverflow.com/a/44225181/6427630 ฉันใช้ @SuppressWarnings() เพื่อสร้าง apk แต่เมื่อใด ฉันพยายามเรียกใช้ ฉันได้รับ java.lang.UnsatisfiedLinkError: dalvik.system.PathClassLoader[DexPathList[[zip file "/data/app/com.dancam.chords-1/base.apk"],nativeLibraryDirectories=[/data/app/com.dancam.chords-1/lib/x86, /system/lib, /vendor/lib]]] couldn't find "libsoundtouch.so" บนบรรทัด System.loadLibrary("soundtouch") มีความคิดใดว่าทำไมสิ่งนี้ถึงเกิดขึ้น? ไฟล์ .so อยู่ในโฟลเดอร์ app/jniLibs ของฉัน   -  person Daniele    schedule 07.09.2017
comment
ใช่ ฉันเชื่อว่าการเปลี่ยนไปใช้ externalNativeBuild เป็นวิธีที่ดีที่สุดในการแก้ไขปัญหาของคุณ   -  person Alex Cohn    schedule 07.09.2017
comment
ตามภาพหน้าจอของคุณ ไฟล์ .so อยู่ในโฟลเดอร์ app/libs คุณสามารถกำหนดค่าการไล่ระดับให้รับจากที่นั่นได้ แต่จะมีประโยชน์กว่ามากหากเปิดใช้งานบิลด์แบบรวม   -  person Alex Cohn    schedule 07.09.2017
comment
คำถามของคุณสับสนมาก บันทึกของคุณแนะนำให้ใช้ Mac แต่ภาพหน้าจอมาจาก Linux บันทึกดูเหมือนว่ามาจากคำสั่งมากกว่าหนึ่งคำสั่งที่อินเทอร์เลซ และข้อโต้แย้ง -B -n นั้นแปลกมาก คุณได้รับบันทึกเหล่านี้มาได้อย่างไร?   -  person Alex Cohn    schedule 09.09.2017
comment
@AlexCohn คุณพูดถูกแล้วที่ไม่ได้พูดอย่างนั้น จริงๆ แล้ว ฉันรวบรวมไลบรารีบน Ubuntu Linux แล้วคัดลอกบน Mac ที่ฉันทำงานตามปกติ   -  person Daniele    schedule 09.09.2017


คำตอบ (2)


ฉันเห็นว่าคุณมีปัญหาในการสร้าง libsoundtouch.so ใน Android Studio สิ่งนี้เกิดขึ้นเช่น เมื่อสคริปต์การสร้างของไลบรารีส่วนที่สามต้องการสภาพแวดล้อมพิเศษ เช่น. วิธีเดียวที่รองรับในการสร้าง webrtc สำหรับ Android คือบน Linux 64 บิต

ในกรณีนี้ คุณสามารถใช้ไลบรารีที่สร้างไว้ล่วงหน้าได้ ใส่ไว้ในโฟลเดอร์ jniLibs ใต้โปรเจ็กต์ของคุณ (jniLibs/armeabi-v7a/libsoundtouch.so ฯลฯ) หรือตั้งค่า โฟลเดอร์ที่กำหนดเองสำหรับ jniLibs ใน build.gradle (ในบล็อก android {}):

sourceSets.main.jniLibs.srcDir 'libs'

คุณไม่ควรใช้ externalNativeBuild.ndkBuild.path ร่วมกับสิ่งนี้

person Alex Cohn    schedule 09.09.2017
comment
ขอบคุณ Alex อีกครั้ง แต่ห้องสมุดที่สร้างไว้ล่วงหน้าคืออะไร? สิ่งที่ฉันใช้คือสิ่งที่ฉันสร้างบน Linux 64 บิต - person Daniele; 09.09.2017
comment
ใช่ รายการที่คุณคัดลอกมาจากเครื่องบิลด์ Linux - person Alex Cohn; 09.09.2017
comment
ในที่สุดการสร้าง gradle ก็สำเร็จ ขอบคุณสำหรับสิ่งนั้น ฉันมีปัญหาเมื่อเรียกวิธีการที่เกี่ยวข้องกับห้องสมุด โปรดตรวจสอบคำถามที่แก้ไขแล้ว - person Daniele; 10.09.2017
comment
โปรดเปิดคำถามแยกต่างหาก ได้ฟรีบนไซต์นี้ คำถามเหล่านี้มีจุดมุ่งหมายเพื่อช่วยเหลือผู้อื่นเช่นกัน การเปลี่ยนเรื่องซ้ำแล้วซ้ำเล่าทำให้ติดตามได้ยาก - person Alex Cohn; 10.09.2017

คุณควรตั้งค่าโปรเจ็กต์ gradle ของคุณเพื่อสร้างไลบรารี C ++

โปรดเพิ่มบรรทัดต่อไปนี้ลงใน build.gradle ของคุณ (ภายในบล็อก android {}):

externalNativeBuild.ndkBuild.path = 'jni/Android.mk'

(สมมติว่าเส้นทาง ~/AndroidStudioProjects/Chords2/app/build.gradle และ ~/AndroidStudioProjects/Chords2/app/jni/Android.mk)

เพื่อลดเวลาในการคอมไพล์และขนาด APK คุณสามารถกรอง ABI ที่คุณไม่ได้ใช้ออกได้ อย่างน้อยที่สุดในขณะแก้ไขจุดบกพร่อง:

ndk { abiFilters 'armeabi-v7a' }

บรรทัดนี้เข้าไปภายในบล็อก defaultConfig {}

อย่างไรก็ตาม หลังจาก APK พร้อมแล้ว คุณสามารถใช้ สร้าง/วิเคราะห์ APK จากเมนูของ Android Studio และตรวจสอบว่ามีไฟล์ .so ทั้งหมดรวมอยู่ในนั้นแล้ว

person Alex Cohn    schedule 07.09.2017
comment
ขอบคุณ จะลองดูในอีกสักครู่ - person Daniele; 07.09.2017
comment
โปรดดูคำถามที่แก้ไขแล้ว ฉันกำลังเผชิญกับปัญหาเหล่านั้นหลังจากทำตามที่คุณบอกฉัน คุณรู้วิธีจัดการกับพวกเขาหรือไม่? - person Daniele; 07.09.2017
comment
กฎข้อแรก: ห้ามใช้ช่องว่างในเส้นทางเมื่อคุณจัดการกับ Android NDK (และ SDK) - person Alex Cohn; 07.09.2017
comment
ขอบคุณ การเปลี่ยนชื่อไดเร็กทอรีนั้นทำให้ฉันได้ความรู้เพิ่มขึ้นอีกเล็กน้อย อย่างน้อยตอนนี้ก็เริ่มลบเนื้อหา armeabi-v7a ออก ยังคงวางสายอยู่ที่ไหนสักแห่ง โปรดตรวจสอบคำถามที่อัปเดตพร้อมบันทึกใหม่ - person Daniele; 07.09.2017
comment
ลองลบไดเร็กทอรี build และสร้างใหม่ทั้งหมด - person Alex Cohn; 07.09.2017
comment
ฉันพยายามทำความเข้าใจว่าคุณวางข้อความแสดงข้อผิดพลาดใดบ้าง แต่ก็ไม่สมเหตุสมผล ฉันไม่รู้ว่า -B -n มาจากคำสั่ง ndk-build แบบรวมที่ไหน - person Alex Cohn; 07.09.2017
comment
ฉันกำลังพยายามอัปเดต NDK ให้เป็นเวอร์ชันล่าสุด หากไม่ได้รับการแก้ไข ฉันอาจจะเริ่มให้เงินรางวัล ฉันไม่รู้จะทำยังไงแล้วจริงๆ ฉันยังตรวจสอบคำแนะนำมากมายเกี่ยวกับวิธีการนำเข้าไลบรารี .so และมันก็ค่อนข้างง่าย ไม่รู้ว่าทำไมฉันถึงได้รับข้อผิดพลาดทั้งหมดนี้ - person Daniele; 08.09.2017
comment
หลังจากอัปเดต NDK เป็น r15c ฉันได้รับบันทึกข้อผิดพลาดใหม่มาให้คุณตรวจสอบ :) - person Daniele; 08.09.2017