3. 강한용
- LINE ARCADE 개발 및 출시 (2016. 3 ~ 2017. 2)
- 네이버 Clova Speech ML Engineer (2017. 3 ~ 현재)
4. 모바일 앱의 흐름
- 새로운 사용자 가치
- 프라이버시 이슈
Deep Learning, VR, AR 등 신기술 등장
5. - JNI를 이용하여 안드로이드에서 네이티브 코드를 구동할 수 있게 해주는 Development Kit
- 다양한 아키텍처에 대한 Cross Compile을 가능하도록 하는 것이 핵심 기능
- 이외에도 안드로이드 SDK를 지원하기 위한 시스템 헤더 및 라이브러리 제공
NDK 정의
NDK란 ?
6. 딥러닝 추론, 이미지 처리 등 높은 성능을 필요로 하는 경우
ex. Deep Learning Framework는 NDK 사용하여 빌드
(tf-lite, OnnxRuntime, PytorchMobile)
02. 코드 재사용
C++ 모듈을 aOS, iOS에서 동시 사용 가능
03. 하드웨어 제어
하드웨어 드라이버 제어
NDK 장점
NDK 사용하는 이유
01. 성능
7. 언제나 모든 플랫폼에서 사용 가능한지를 체크해야 한다.
02. 안정성 결여
네이티브 메소드는 자바 메소드처럼 보호를 받지 못한다.
메모리 추적, 포인터 사용 등에 의한 C++의 버그가 발생한다.
03. 보안에 취약
.so와 같은 동적 라이브러리의 호출은 자바 시큐리티 메니저의 의도에 반한다.
NDK 단점
NDK 사용 안 하는 이유
01. 이식성 결여
04. 복잡성 증가
프로그램을 설계할 때, 프로젝트를 진행할 때, 나중에 유지 보수할 때 복잡할 수 있다.
10. JNI 정의
JNI 란?
native printHello()
Java_HelloJNI_printHello()
자바 가상 머신
- System.load()를 호출하면 VM이 native로 선언된 메소드를 로딩한 라이
브러리의 native 함수로 연결
- libfubar.so를 로드하려면 fubar
RegisterNatives
- JNI_OnLoad를 추가해 놓으면 JNI_OnLoad만 연결
- 네이티브 함수 코드를 클래스의 native 메소드에 연결
- VM이 링크하는 것보다 훨씬 능률적이고 빠름
11. JNI 정의
JNI 란?
native printHello() Java_HelloJNI_printHello()
JVM
C App
RegisterNative 함수를 이용하여
JVM에 링크
12. JNIEXPORT jint JNI_OnLoad(JavaVM* vm, void* reserved) {
JNIEnv* env;
if (vm->GetEnv(reinterpret_cast<void**>(&env), JNI_VERSION_1_6) != JNI_OK) {
return JNI_ERR;
}
// Find your class. JNI_OnLoad is called from the correct class loader context for this to work.
jclass c = env->FindClass("com/example/app/package/MyClass");
if (c == nullptr) return JNI_ERR;
// Register your class' native methods.
static const JNINativeMethod methods[] = {
{"nativeFoo", "()V", reinterpret_cast<void*>(nativeFoo)},
{"nativeBar", "(Ljava/lang/String;I)Z", reinterpret_cast<void*>(nativeBar)},
};
int rc = env->RegisterNatives(c, methods, sizeof(methods)/sizeof(JNINativeMethod));
if (rc != JNI_OK) return rc;
return JNI_VERSION_1_6;
}
JNI 정의
JNINativeMethod 구조체
typedef struct {
char *name;
char *signature;
void *fnPtr;
} JNINativeMethod
jint RegisterNatives(JNIEnv *env,
Jclass clazz,
Const JNINativeMethod
*methods,
Jint nMethods);
13. JNIEnv interface pointer
- 네이티브 메소드의 첫 번째 인자로 전달됨
- 현재 쓰레드 에서만 유효 (다른 쓰레드에서 사용할 수 없음)
- 함수 테이블의 포인터를 갖고 있음
- 네이티브 메소드는 JNI 함수를 통해 Java VM의 데이터 구조에 접근 가능
Pointer
(Internal
virtual
machine data
structures)
Pointer
Pointer
Pointer
…
an interface function
an interface function
an interface function
JNIEnv*
14. JNI 정의
스트링을 줄게.
근데 Java.lang.String
형 알아?
몰라!
하지만
GetStringUTFChars를
통해 알 수 있어
이렇게 얻어온 스트링은
ReleaseStringUTFChar
s로 해제 해줘야 해
16. ABI (Application Binary Interface)
ABI 지원되는 명령 세트 예시 기기
armeabi-v7a armeabi
Thumb-2
VFPv3-D16
갤럭시 S5
arm64-v8a AArch64 갤럭시 S5 이상
x86 x86
MMX
SSE/2/3
SSSE3
x86_64 x86-64
MMX
SSE/2/3
SSSE3
SSE4.1, 4.2
POPCNT
17. NDK OS 변형 호스트 태그
macOS darwin-x86_64
Linux linux-x86_64
32비트 Windows windows
64비트 Windows windows-x86_64
ABI 타깃
armeabi-v7a armv7a-linux-androidabi
arm64-v8a aarch64-linux-android
x86 i686-linux-android
x86-64 x86_64-linux-android
ABI (Application Binary Interface)
18. ndk-build vs CMake
- 결과물은 같습니다. 더 편한 걸 쓰면 됩니다.
- 그러나 선택해야 한다면 CMake를 추천합니다.
- iOS, C++ 빌드 시 CMakeLists.txt를 재사용할 수 있습니다.
- 비교적 친숙하고 널리 쓰입니다.
- 안드로이드 기본 빌드는 CMake입니다.
19. android {
...
defaultConfig {...}
buildTypes {...}
// Encapsulates your external native build configurations.
externalNativeBuild {
// Encapsulates your CMake build configurations.
cmake {
// Provides a relative path to your CMake build script.
path "CMakeLists.txt"
}
}
}
20. JNI Heap 관리
- JNI 참조는 네이티브 코드에 의해 수동으로 관리되므로 네이티브 코드에서
사용하는 자바 개체가 너무 오랫동안 연결된 상태로 유지될 수 있습니다.
JNI 참조가 먼저 명시적으로 삭제되지 않고 취소되면 자바 힙의 일부
개체에 도달하지 못할 수도 있습니다. 또한 글로벌 JNI 참조 한도를 소진할
수도 있습니다.