java.lang.UnsatisfiedLinkError: не найдена реализация для логического значения

Я использую файлы ".so" в своем проекте, но выдает следующую ошибку "java.lang.UnsatisfiedLinkError: не найдена реализация для логического значения", я уже пытаюсь воссоздать ".so" с помощью Cygwin и поместить его в папке jniLibs, а также с помощью создания его jar, но это дает ту же ошибку.

Но тот же файл «.so» работает в моем существующем проекте. Я пробовал так много способов, но это не работает вообще, что я могу сделать?

com.amaze.filemanager E/art: No implementation found for boolean com.amaze.filemanager.scanner.SignatureLib.InitScanner(java.lang.String, java.lang.String) (tried Java_com_amaze_filemanager_scanner_SignatureLib_InitScanner and Java_com_amaze_filemanager_scanner_SignatureLib_InitScanner__Ljava_lang_String_2Ljava_lang_String_2) 12-19 11:47 :07.463 4579-4934/com.amaze.filemanager E/AndroidRuntime: НЕИСПРАВНОЕ ИСКЛЮЧЕНИЕ: Thread-5230 Процесс: com.amaze.filemanager, PID: 4579 java.lang.UnsatisfiedLinkError: Не найдена реализация для логического com.amaze.filemanager.scanner .SignatureLib.InitScanner(java.lang.String, java.lang.String) (пробовали Java_com_amaze_filemanager_scanner_SignatureLib_InitScanner и Java_com_amaze_filemanager_scanner_SignatureLib_InitScanner__Ljava_lang_String_2Ljava_lang_String_2) в com.amaze.filemanager.scanner.SignatureLib.InitScanner(собственный метод) в com.amaze.filemanager.scanner.SignatureLib.InitializeScanner(SignatureLib.java:42) в com.amaze.filemanager.scanner.Signature.(Signature.java :62) в com.amaze.filemanager.ScanForVirusActivity$1.run(ScanForVirusActivity.java:66)

public class SignatureLib {

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

    SharedPreferencesUtils spu;
    Context context;

    public SignatureLib(Context context) {
        this.context = context;
    }

    private native boolean InitScanner(String strDBPath, String dbPathTemp);

    private native boolean DeInitScanner();

    private native String checkVirus(String filepath);

    private native boolean UploadFile(String FilePath, String DeviceID, String path);

    private native boolean DownloadFile(String FilePath, String DeviceID, String path);

    private native boolean IsGameApp(String AppName);

    private native boolean SetUpdateInProgressStatus(boolean bStatus);

    public boolean InitializeScanner(String strDBPath) {

        spu = new SharedPreferencesUtils();
        String packageName = context.getPackageName();
        String dbPathTemp = "data/data/" + packageName + "/";

        return InitScanner(strDBPath, dbPathTemp);
    }

}

person Faheem Raza    schedule 16.12.2016    source источник
comment
Опубликуйте полную трассировку стека и код, который вызывает эту ошибку.   -  person Gabe Sechan    schedule 16.12.2016
comment
Я помещаю свою трассировку стека и код, он дает мне ошибку в return InitScanner(strDBPath, dbPathTemp), пожалуйста, помогите мне   -  person Faheem Raza    schedule 16.12.2016


Ответы (2)


Да, нужна была полная трассировка стека — изначально вы прервали ее в бессмысленном месте. Это говорит о том, что в вашем файле .so нет функции InitScanner - либо вы неправильно назвали его в файле C, вы неправильно указали подпись, либо его там нет вообще. Или, если вы использовали C++, вы забыли внедрить функцию C.

person Gabe Sechan    schedule 16.12.2016
comment
Уверены, что .so правильно находится в файле apk? А для правильного чипсета? Ошибка, которую вы опубликовали, означает, что она не находит функцию. - person Gabe Sechan; 17.12.2016
comment
Я поставил полный стек, но тот же код класса SignatureLib и С++ работает в существующем продукте, так что я ошибаюсь - person Faheem Raza; 17.12.2016
comment
@FaheemRaza, ты смог решить проблему? Пожалуйста, поделитесь, поскольку я сталкиваюсь с подобным. - person saintjab; 31.05.2017

В моем java-файле я загрузил имя моей библиотеки с именем «native-lib» в нижеприведенном статическом блоке.

package primeno.naval.com.primenumberusingndk;
static
{
  System.loadLibrary("native-lib");
}

здесь я объявил две функции, и их реализация находится в файле CPP.

public native String stringFromJNI();
public native boolean isPrime(int n);

мой файл cpp с вышеприведенной реализацией функции

extern "C"
JNIEXPORT jstring JNICALL Java_primeno_naval_com_primenumberusingndk_MainActivity_stringFromJNI(
JNIEnv *env,
jobject /* this */) {
std::string hello = "Hello from C++";
return env->NewStringUTF(hello.c_str());
}

extern "C"
JNIEXPORT jboolean JNICALL Java_primeno_naval_com_primenumberusingndk_MainActivity_isPrime(JNIEnv *env,jobject ,jint no)
{
PrimeNumber primeNumber(no);
return primeNumber.isPrime();
}

или вы можете сделать так же

extern "C" {

    JNIEXPORT jstring JNICALL Java_primeno_naval_com_primenumberusingndk_MainActivity_stringFromJNI(
    JNIEnv *env,
    jobject /* this */) {
    std::string hello = "Hello from C++";
    return env->NewStringUTF(hello.c_str());
    }

    JNIEXPORT jboolean JNICALL Java_primeno_naval_com_primenumberusingndk_MainActivity_isPrime(JNIEnv *env,jobject ,jint no)
    {
    PrimeNumber primeNumber(no);
    return primeNumber.isPrime();
    }
}

Если несоответствие в имени функции и подписи не имеет места, вам нужно написать extern «C» перед каждой функцией в файле cpp, поэтому фактический формат соглашения об именах

extern "C" JNIEXPORT <RETURN_TYPE> JNICALL Java_<PACKAGE_NAME>_<JAVA_CLASS>_<METHOD_NAME>(
JNIEnv *env, jobject obj, <METHOD_PARAMETERS>...) {
...
}

extern "C":

Заявление о том, чтобы имена функций C++ были связаны с C. Чтобы поддерживать перегрузку функций, компиляторы C++ искажают имена функций, что означает, что имена функций C++ не такие, как в C. Без внешнего «C» сигнатуры ваших собственных функций не будут соответствовать их объявлениям в Java (во время выполнения). Короче говоря, вам нужен этот оператор для каждого метода, если вы пишете собственный C++, а не C.

JNIEXPORT:

Содержит директивы компилятора, необходимые для правильного экспорта функции.

<RETURN_TYPE>:

Возвращаемый тип метода JNI, обычно собственная версия типа Java. Например, в методе, который вы только что написали выше, вы возвращаете jstring, который является нативным эквивалентом String в Java.

JNICALL: C

содержит директивы компилятора, необходимые для обеспечения того, чтобы функция обрабатывалась с надлежащим соглашением о вызовах JNI.

<JAVA_CLASS>:

Соединительный класс Java, к которому привязана эта функция. В нашем примере это будет MainActivity, так как это класс Java, который будет использовать эту функцию.

<PACKAGE_NAME>:

Имя пакета, в котором находится ранее определенный <JAVA_CLASS>. Замените точки (.) символами подчеркивания (_).

<METHOD_NAME>:

Это имя должно совпадать с тем, которое вы объявляете внутри подключаемого файла . В нашем примере мы объявили нативный метод getNativeString(). В этом случае также должен быть getNativeString().

JNIEnv *env:

Указатель на структуру (точнее, таблицу функций), в которой хранятся все указатели вспомогательных функций JNI, включая ту, которую мы вызываем в нашем примере, NewStringUTF(string). Чтобы иметь возможность использовать эти функции, вам нужно #include .

jobject obj:

Объект Java, соответствующий соединению<JAVA_CLASS>.

<METHOD_PARAMETERS>...:

Разделенный запятыми список входных аргументов, которые должен принимать собственный метод. В нашем примере у нас нет входных аргументов для нашей функции getNativeString(), поэтому поле остается пустым.

person Naval Kishor Jha    schedule 14.03.2018
comment
Это не ответ на вопрос, и вам не нужно ничего этого делать: просто включите файл .h в файл .cpp. Пожалуйста, прекратите использовать SCRAMING BOLDFACE. - person user207421; 15.03.2018
comment
Привет, EJP, вот пример git github.com/NavalKishor/PrimeNumberUsingNdk, вы просто прокомментируете extern C в src/main/../cpp/native-lib в git и при компиляции вы получите ту же ошибку java.lang.UnsatisfiedLinkError: Реализация не найдена для и (пробовал это... и это...), затем вы найдете ответ делать то, что нужно - person Naval Kishor Jha; 17.03.2018
comment
@EJP вы тестировали вышеупомянутый случай - person Naval Kishor Jha; 18.03.2018