JNIEXPORT 및 JNICALL은 NDK_ROOT/platforms/android-9/arch-arm/usr/include/jni.h에 정의되어 있습니다. 설정에 따라이 경로는 달라 지지만 대부분 유사합니다.
#define JNIIMPORT
#define JNIEXPORT __attribute__ ((visibility ("default")))
#define JNICALL
JNIEXPORT는 빌드 된 바이너리 (* .so 파일)의 동적 테이블에 기본 함수를 표시하는 데 사용됩니다. "숨김"또는 "기본"으로 설정할 수 있습니다 (추가 정보 here). 이러한 함수가 동적 테이블에없는 경우 JNI는 호출 할 함수를 찾을 수 없으므로 런타임에 RegisterNatives 호출이 실패합니다.
모든 기능이 기본적으로 동적 테이블에 저장되므로 누구나 쉽게 네이티브 코드를 디 컴파일 할 수 있습니다. JNI가 그것을 찾아야하는 경우를 대비하여 모든 함수 호출은 바이너리에 내장되어 있습니다. 이 옵션은 컴파일러 옵션 -fvisibility
을 사용하여 변경할 수 있습니다. 모든 사람들이 코드를 안전하게 유지하기 위해 이것을 -fvisibility=hidden
으로 설정 한 다음 JNIEXPORT를 사용하여 함수에 외부 공개 여부를 표시하는 것이 좋습니다.
strip 명령을 사용하면 디버그 기호가 제거되고 동적 테이블은 분리됩니다. objdump로 놀아서 사람이 .so 파일에서 얼마나 벗어날 수 있는지 확인하십시오.
최근에 우리는이 문제로 인해 어려움에 처했습니다.
EDIT : 우리는 사용자 정의 빌드 시스템을 사용하므로 가시성 옵션이 다른 빌드 설정을 위해 기본적으로 설정 될 수 있습니다. 자세한 내용은 this SO answer에서 확인할 수 있습니다. 간단한 측면에서
JNICALL은 무엇을 의미합니까? – Lealo
JNICALL은 (위와 같이) 안드로이드에서 비어있는 정의이지만 플랫폼 호환성을 위해 존재합니다. Windows JDK JNICALL은'__stdcall' (https://msdn.microsoft.com/en-us/library/zxk0tw93.aspx)로 정의되어 있습니다. –