jni '__ - `__android_log_print '에 대한 정의되지 않은 참조




출력 로그 (11)

make 파일에 어떤 문제가 있습니까?

Android.mk

LOCAL_PATH := $(call my-dir)

include $(CLEAR_VARS)
LOCAL_MODULE    := foo
LOCAL_SRC_FILES := foo.c
LOCAL_EXPORT_LDLIBS := -llog
include $(BUILD_SHARED_LIBRARY)

foo.c

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

#define  LOG_TAG    "foo"
#define  LOGI(...)  __android_log_print(ANDROID_LOG_INFO, LOG_TAG, __VA_ARGS__)

void test() {
    LOGI("test");
}

ndk-build

foo.c:9: undefined reference to `__android_log_print'

Answers

더하다

LOCAL_SHARED_LIBRARIES:= \
        libbinder                       \
        liblog                          \

Android.mk에


Android Studio를 사용하고 gradle을 사용하는 경우 Android.mk가 무시됩니다. 이 파일을 build.gradle 파일에 추가하십시오.

android {
    defaultConfig {
        ndk {
            moduleName "your_module_name"
            ldLibs "log"
        }
    }
}

예, LOCAL_LDLIBS := -llog 를 다른 답변 / 주석이 지정한대로 추가해야하지만 원래 질문은 jni 라이브러리를 LOCAL_JNI_SHARED_LIBRARIES 또는 LOCAL_JNI_SHARED_LIBRARIES 로 사용할지 여부를 지정하지 않았습니다.

나는 꽤 많이 그가 말할 수 있습니다 : LOCAL_REQUIRED_MODULES 때문에 LOCAL_EXPORT_LDLIBS := -llog 질문에 ... - 그게 편집 후에 추가되지 않은 경우.

LOCAL_REQUIRED_MODULES 를 사용하면 공유 라이브러리는 필수 모듈이므로 apk 대신 / system / lib에 설치됩니다. 따라서 LOCAL_LDLIBS := -L$(SYSROOT)/usr/lib -llog 대신 LOCAL_LDLIBS := -L$(SYSROOT)/usr/lib -llog 를 추가해야합니다 LOCAL_LDLIBS := -L$(SYSROOT)/usr/lib -llog 이렇게하면 빌드 시스템이 jni 공유 라이브러리를 빌드하고 링크 할 때 -llog $OUT/root/system/lib 아래에 빌드 할 수있는 정확한 위치의 정의. 그렇지 않으면 LOCAL_LDLIBS := -llog 만 추가하더라도 동일한 답을 계속 얻을 수 있습니다.

따라서 -L 이 필요 없다고 답한 사람들은 다른 대답이 맞았습니다.이 상황에서는 실제로 잘못되었습니다.


대신에

Android Studio 1.3에서 새로운 Gradle NDK 통합을 사용하는 경우 android.ndk 옵션에 ldLibs = [ "android", "log"]를 추가해야합니다. - Stephen Kaiser Sep 24 at 4:20

실험용 플러그인에 대해 ldLibs.addAll(["android", "log"]) 을 사용하십시오.


Android.mk 파일에서 다음을 시도하십시오.

LOCAL_LDLIBS := -L$(SYSROOT)/usr/lib -llog

당신이 작업하고있는 프로젝트가 다른 '표준'답변과 다른 다음과 같은 특징을 가지고있는 경우 :

  • Android Studio를 사용하지 않음
  • gradle 및 통합 된 CMake 사용하지 않음
  • 빌드를 위해 Android.mk 또는 Application.mk를 전혀 사용하지 않았습니다.
  • CMake와 toolchain을 직접 사용하기 (프로젝트가 Qt 기반이고 QtCreator를 사용하지 않고있을 수도 있음)

다음과 같은 target_link_libraries 사용법을 사용합니다.

    find_library(ANDROID_LOG_LIB log)
    target_link_libraries(${TARGET_NAME} ${ANDROID_LOG_LIB})

TARGET_NAME 은 ( add_library 또는 add_executable 하여 이전에 설정 한) 빌드 할 대상의 이름입니다.

find_library 는 toolchain을 올바르게 설정하는 것만큼이나 중요합니다 ( ANDROID_SDK_HOME/cmake/<version>/android.toolchain.cmake Android SDK에서 제공하는 toolchain을 사용하여 find_ 명령에서 사용되는 find_ 합니다).


이것은 나를 위해 도움이되었습니다 :

Android.mk

    LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)

LOCAL_MODULE    := nativeDemo
LOCAL_SRC_FILES := main.cpp
LOCAL_LDLIBS += -llog

include $(BUILD_SHARED_LIBRARY)

추가해야합니다.

LOCAL_LDLIBS := -llog

Android.mk에


android studio 버전 2.2 이상에서는 새 프로젝트를 만들 때 CPP에 대한 내장 된 지원이 있습니다. 또한 기본적으로 liblog.so가 포함되어 있습니다. 헤더 파일 (android / log.h)을 포함하는 것 외에는 수행 할 작업이 없습니다.

우리가 새로운 android studio 프로젝트를 만들 때 스튜디오에 의해 생성 된 Checkout app / CMakeLists.txt. loglib에 대한 find_library () 블록 및 target_link_libraries () 블록이 이미 있음을 알 수 있습니다.

또한 함수 구문에주의하십시오. 그것은해야한다:

__android_log_print (int 우선 순위, const char * 태그, const char * fmt, ...);

필자의 경우에는 태그 매개 변수를 생략하고 3 일 동안 지출을 끝내기 시작했습니다.

CMake에 대한 추가 정보 : 프로젝트에 C 및 C ++ 코드 추가하기


Android Studio 2.1로 업그레이드하면 위의 답변이 작동하지 않으므로 아래와 같이 lib를로드하려면 ldLibs.add ()를 사용해야합니다.

android.ndk {
    moduleName = "[the_module_name]"
    ldLibs.addAll(['android', 'log'])
}

이것은 내 개인적인 경험입니다.

악명 높은 싱글 SQLqlOpenHelper 접근법에 코드를 적용한 후에는 헬퍼 객체가 해당 객체에 대한 모든 db 액세스를 동기화하므로 상황이 개선되었습니다. 그러나 여전히, 그것은 아직 최고가 아니었다.

보아라.이 모든 것들은 정말로 원자력이 아니며, 당신이 통제 할 수없는 영역에서 일어난다. 쿼리 직전에 연결이 잠금을 가진 다른 스레드에 의해 닫혔다 고 가정하십시오.

쿼리하기 전에 연결을 확인할 수 있지만 닫힌 경우 어떻게됩니까? 네가해야 할 일을하는 걸 건너 뛰는거야? 또는 컨트롤이있는 수준에서 특정 db 액세스 허브에 대한 간단한 동기화를 구현할 수 있습니까? 나는 확실히 두 번째 길을 택할 것이다.







android jni logging android-ndk