Android ndk c ++ jni (nenhuma implementação encontrada para nativo…)
-
25-09-2019 - |
Pergunta
Estou tentando usar o NDK com C ++ e não consigo correr a convenção de nomeação do método correta. Meu método nativo é o seguinte:
extern "C" {
JNIEXPORT void JNICALL Java_com_test_jnitest_SurfaceRenderer_drawFromJni
(JNIEnv* env, jclass c)
{
//
}
}
com um cabeçalho embrulhado em extern "C" {} ASLO.
Tudo compila bem, cria um arquivo .So e cópias para a pasta LIBS no meu projeto, mas quando eu depurar e executar no Eclipse, continuo recebendo uma mensagem de log de gato que "nenhuma implementação foi encontrada para o nativo ...". Há algo que estou perdendo, pois todos os exemplos do NDK estão em C?
Obrigado.
Solução
Há algumas coisas que podem levar a "nenhuma implementação encontrada". Um está errando o nome do protótipo de função, outro está não carregando o. Então. Você está certo disto System.loadLibrary()
está sendo chamado antes que o método seja usado?
Se você não tem um JNI_OnLoad
Função Definida, você pode criar um e cuspir uma mensagem de log apenas para verificar se a lib está sendo puxada com sucesso.
Você já se esquivou do problema mais comum - esquecendo de usar extern "C"
- Então é o acima ou um pouco de ortografia. Como é a declaração de Java?
Outras dicas
Uma causa adicional para este erro: seu nome de método nativo não decorado não deve conter um sublinhado!
Por exemplo, eu queria exportar uma função C nomeada AudioCapture_Ping()
. Aqui está minha declaração de exportação em C:
JNI_EXPORT int Java_com_obsidian_mobilehashhost_MainActivity_AudioCapture_Ping(JNIEnv *pJniEnv, jobject object); //Notice the underscore before Ping
Aqui estava minha classe Java importando a função:
package com.obsidian.mobileaudiohashhost;
...
public class MainActivity extends Activity {
private native int AudioCapture_Ping(); // FAILS
...
Não consegui fazer o Android se vincular dinamicamente ao meu método nativo até remover o sublinhado:
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!
...
Eu tive o mesmo problema, mas para mim o erro estava no arquivo android.mk. Eu tinha isso:
LOCAL_SRC_FILES := A.cpp
LOCAL_SRC_FILES := B.cpp
mas deveria ter isso:
LOCAL_SRC_FILES := A.cpp
LOCAL_SRC_FILES += B.cpp
Observe o detalhe += em vez de :=
Espero que isso ajude.
Chamado externo "C", conforme fornecido no exemplo de estúdio gerado automaticamente, mas esqueci de envolver todo o restante do arquivo, incluindo as seguintes funções, nos colchetes {}. Somente a primeira função funcionou.
Um motivo adicional: use local_whole_static_libraries em vez de local_static_libraries no android.mk. Isso impede que a biblioteca otimize chamadas de API não utilizadas porque o NDK não pode detectar o uso das ligações nativas do código Java.
Há um exemplo de CPP em aplicativos no NDK:https://android.googlesource.com/platform/development/+/marshmallow-release/ndk/platforms/android-5/samples/hello-gl2/jni/gl_code.cpp
Use Javah (parte do Java SDK). É a ferramenta exatamente para isso (gera cabeçalho .h a partir do arquivo .class).
Se o nome do seu pacote incluir _ caractere, você deve escrever 1 (um) após _ caractere como mostrado abaixo:
MainActivity.java
package com.example.testcpp_2;
nativo-lib.cpp
JNICALL
Java_com_example_testcpp_12_MainActivity_stringFromJNI(
Eu tento todas as soluções acima, mas ninguém pode resolver meu erro de construção (jni java.lang.unsatisfiedlinkerror: nenhuma implementação encontrada para ...), finalmente descobri que esqueci de adicionar meu arquivo de origem verificado.cpp ao cmakelist.txt add_library segem (verify.cpp é gerado automaticamente por ctrl + digite a chave curta, talvez outro nome de arquivo), espero que minha resposta possa ajudar alguém.
Meu ambiente de construção: gradle + cmake
Eu enfrentei o mesmo problema e, no meu caso, o motivo era que eu tinha sublinhado no nome do pacote "rfid_test", renomeei o pacote e ele funcionou. Obrigado User1222021
Eu enfrentei o mesmo problema duas vezes. Aconteceu que o telefone que tentei iniciar o aplicativo do Android Studio usou um Nível da API Que ainda não baixei no Android Studio.
- Atualize o Android Studio para a versão mais recente
- Faça o download da API necessária do Android Studio