Próbuję użyć NDK z C ++ i nie mogę uzyskać poprawnej konwencji nazewnictwa metod. moja natywna metoda jest następująca:
extern "C" {
JNIEXPORT void JNICALL Java_com_test_jnitest_SurfaceRenderer_drawFromJni
(JNIEnv* env, jclass c)
{
//
}
}
z nagłówkiem zawiniętym w extern „C” {} aslo.
Wszystko dobrze się kompiluje, tworzy plik .so i kopiuje do folderu libs w moim projekcie, ale kiedy debuguję i uruchamiam w Eclipse, ciągle otrzymuję komunikat „Nie znaleziono implementacji dla natywnego…”. Czy jest coś, czego mi brakuje, ponieważ wszystkie przykłady NDK są w C?
Dzięki.
android
android-ndk
Patrick Kafka
źródło
źródło
javah
? Jeśli nie, powinieneś. :-PSystem.loadLibrary
Odpowiedzi:
Jest kilka rzeczy, które mogą prowadzić do „braku implementacji”. Jeden z nich powoduje błędną nazwę prototypu funkcji, inny w ogóle nie ładuje pliku .so. Czy na pewno
System.loadLibrary()
jest wywoływana przed użyciem metody?Jeśli nie masz
JNI_OnLoad
zdefiniowanej funkcji, możesz ją utworzyć i poprosić o wyplucie komunikatu dziennika tylko po to, aby sprawdzić, czy biblioteka jest pomyślnie pobierana.Już uniknąłeś najczęstszego problemu - zapomnienia o użyciu
extern "C"
- więc jest to albo powyższe, albo drobna literówka. Jak wygląda deklaracja Java?źródło
Dodatkowa przyczyna tego błędu: Twoja niezdekorowana nazwa metody natywnej nie może zawierać podkreślenia!
Na przykład chciałem wyeksportować funkcję C. o nazwie
AudioCapture_Ping()
. Oto moje zgłoszenie wywozowe w C:JNI_EXPORT int Java_com_obsidian_mobilehashhost_MainActivity_AudioCapture_Ping(JNIEnv *pJniEnv, jobject object); //Notice the underscore before Ping
Oto moja klasa Java importująca funkcję:
package com.obsidian.mobileaudiohashhost; ... public class MainActivity extends Activity { private native int AudioCapture_Ping(); // FAILS ...
Nie mogłem zmusić Androida do dynamicznego łączenia się z moją natywną metodą, dopóki nie usunąłem podkreślenia:
JNI_EXPORT int Java_com_obsidian_mobilehashhost_MainActivity_AudioCapturePing(JNIEnv *pJniEnv, jobject object); package com.obsidian.mobileaudiohashhost; ... public class MainActivity extends Activity { private native int AudioCapturePing(); // THIS WORKS! ...
źródło
Miałem ten sam problem, ale dla mnie błąd był w pliku Android.mk. Miałem to:
ale powinien mieć to:
zwróć uwagę na szczegół + = zamiast : =
Mam nadzieję że to pomogło.
źródło
Wywołano extern „C”, jak podano w automatycznie wygenerowanym przykładzie Studio, ale zapomniałem owinąć całą resztę pliku, w tym następujące funkcje, w nawiasy {}. Działała tylko pierwsza funkcja.
źródło
Dodatkowy powód: użyj LOCAL_WHOLE_STATIC_LIBRARIES zamiast LOCAL_STATIC_LIBRARIES w android.mk. Uniemożliwia to bibliotece optymalizację nieużywanych wywołań API, ponieważ NDK nie może wykryć użycia natywnych powiązań z kodu Java.
źródło
Przykład cpp w aplikacjach w ndk: https://github.com/android/ndk-samples/blob/master/hello-gl2/app/src/main/cpp/gl_code.cpp
źródło
Użyj javah (część Java SDK). Jest to narzędzie właśnie do tego (generuje nagłówek .h z pliku .class).
źródło
Jeśli nazwa twojego pakietu zawiera _ znak, powinieneś napisać 1 (jeden) po _ znaku, jak pokazano poniżej:
MainActivity.java
package com.example.testcpp_2;
native-lib.cpp
źródło
Próbuję wszystkich powyższych rozwiązań, ale nikt nie może rozwiązać mojego błędu kompilacji (jni java.lang.UnsatisfiedLinkError: Nie znaleziono implementacji dla ...), w końcu stwierdziłem, że zapomniałem dodać mój plik źródłowy verify.cpp do CMakeList.txt add_library segement (verify.cpp jest automatycznie generowana przez skrót Ctrl + Enter, może inna nazwa pliku), mam nadzieję, że moja odpowiedź może komuś pomóc.
moje środowisko kompilacji: Gradle + CMake
źródło
Napotkałem ten sam problem, aw moim przypadku powodem było podkreślenie w nazwie pakietu „RFID_Test”. Zmieniłem nazwę pakietu i zadziałało. Dzięki user1222021
źródło
Dwukrotnie stanąłem przed tym samym problemem. Zdarzyło się, że telefon, na którym próbowałem uruchomić aplikację z Android Studio, korzystał z poziomu API , którego jeszcze nie pobrałem w Android Studio.
źródło