[android] Android NDK C ++ JNI (네이티브에 대한 구현 없음…)

C ++에서 NDK를 사용하려고하는데 메서드 명명 규칙을 올바르게 얻을 수없는 것 같습니다. 내 기본 방법은 다음과 같습니다.

extern "C" {
JNIEXPORT void JNICALL Java_com_test_jnitest_SurfaceRenderer_drawFromJni
(JNIEnv* env, jclass c)
{
   //
}
}

헤더가 extern “C”{}로 래핑되어 있습니다.

모든 것이 잘 컴파일되고 .so 파일이 생성되고 내 프로젝트 아래의 libs 폴더에 복사되지만 Eclipse에서 디버그하고 실행할 때 “기본에 대한 구현을 찾을 수 없음 …”이라는 로그 고양이 메시지가 계속 표시됩니다. 모든 NDK 예제가 C에 있기 때문에 내가 놓친 것이 있습니까?

감사.



답변

“구현을 찾을 수 없음”으로 이어질 수있는 몇 가지 사항이 있습니다. 하나는 함수 프로토 타입 이름을 잘못 받고 다른 하나는 .so를 전혀로드하지 못하는 것입니다. 당신이 확인되는 System.loadLibrary()방법을 사용하기 전에 호출되고?

JNI_OnLoad정의 된 함수 가없는 경우 라이브러리를 성공적으로 가져 왔는지 확인하기 위해 하나를 만들고 로그 메시지를 뱉어 내도록 할 수 있습니다.

이미 가장 일반적인 문제 (사용하는 것을 잊음)를 피 extern "C"했으므로 위의 내용이거나 약간의 철자 오류입니다. Java 선언은 어떻게 생겼습니까?


답변

이 오류의 추가 원인 : 데코 레이팅되지 않은 네이티브 메서드 이름에 밑줄이 없어야합니다!

예를 들어,라는 C 함수를 내보내고 싶었습니다 AudioCapture_Ping(). 다음은 C로 된 내 수출 선언입니다.

JNI_EXPORT int Java_com_obsidian_mobilehashhost_MainActivity_AudioCapture_Ping(JNIEnv *pJniEnv, jobject object);  //Notice the underscore before Ping

함수를 가져 오는 Java 클래스는 다음과 같습니다.

package com.obsidian.mobileaudiohashhost;
...
public class MainActivity extends Activity {
    private native int AudioCapture_Ping();  // FAILS
    ...

밑줄을 제거 할 때까지 Android가 내 네이티브 메서드에 동적으로 연결되도록 할 수 없습니다.

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


답변

나는 같은 문제가 있었지만 나에게 오류는 Android.mk 파일에있었습니다. 그걸 가졌어:

LOCAL_SRC_FILES := A.cpp
LOCAL_SRC_FILES := B.cpp

하지만 다음이 있어야합니다.

LOCAL_SRC_FILES := A.cpp
LOCAL_SRC_FILES += B.cpp

대신 + = 세부 사항을 참고하십시오 : =

도움이 되었기를 바랍니다.


답변

자동 생성 된 Studio 예제에 제공된대로 extern “C”라고 부르지 만 다음 함수를 포함하여 파일의 전체 나머지 부분을 {} 대괄호로 감싸는 것을 잊었습니다. 첫 번째 기능 만 작동했습니다.


답변

추가 이유 : android.mk에서 LOCAL_STATIC_LIBRARIES 대신 LOCAL_WHOLE_STATIC_LIBRARIES를 사용하세요. 이렇게하면 NDK가 자바 코드에서 네이티브 바인딩 사용을 감지 할 수 없기 때문에 라이브러리가 사용되지 않는 API 호출을 최적화하지 못합니다.


답변


답변

javah (Java SDK의 일부)를 사용하십시오. 이를위한 도구입니다 (.class 파일에서 .h 헤더 생성).