본문 바로가기
공허의 유산/사상의 도구

[android/aar]#00. 배경 지식 대충 감 잡아보기

by 바른생활머시마 2020. 2. 1.
728x90

 Android도 성능이 아주 좋아졌다는 말이 들려서 '성능 때문에 NDK를 해야 한다.'는 말에 의구심이 들기도 했지만, 성능이 중요한 AR/ Graphics 관련 툴들은 NDK 기반인 것이 많네요. 그럴 때 마다 번번히 NDK 때문에 다음으로 미뤘는데, 더이상 미루지 말고 살짝 개념이라도 좀 잡아보고자 합니다.

 

 android의 NDK 관련 페이지도 있긴 한데, 처음 접하는 입장에서는 살짝 부담스러운 것이 사실이죠.

https://developer.android.com/ndk/guides

 

NDK 시작하기  |  Android NDK  |  Android Developers

NDK(Native Development Kit)는 Android에서 C 및 C++ 코드를 사용할 수 있게 해주는 일련의 도구 모음으로, 네이티브 활동을 관리하고 센서 및 터치 입력과 같은 물리적 기기 구성요소에 액세스하는 데 사용할 수 있는 플랫폼 라이브러리를 제공합니다. NDK는 앱을 개발할 때 자바 코드와 프레임워크 API만 사용해야 하는 대부분의 초심자 Android 프로그래머에게는 적합하지 않을 수 있지만 다음과 같은 작업을 하나 이상 해야 하는

developer.android.com

몇 곳 검색을 해 보니, 가장 간단한 곳이 아래 사이트여서, 일단 한번 따라 해 봤습니다.

https://yoo-hyeok.tistory.com/72

 

하고 보니, android studio의 NDK 템플릿을 만들어 실행 해 본 것과 크게 다르지 않았습니만, 시작 할 수 있는 용기를 주는 간단한 내용이라서 좋았습니다. 그 내용 바탕으로 조금 더 살을 붙여 정리 해 봅니다.

 

1. android studio NDK project template로 시작하기

 참고 사이트처럼 쉽게 쉽게 가보도록 하겠습니다. "원래 이렇게 쉬웠나?" 싶지만, 그렇지는 않은 것 같습니다. 원래 좀 복잡했었는데, 개발하기 편리한 환경이 제공되어서 편해진 것 같네요.

 

 android studio를 시작하고, 새로운 프로젝트를 만듭니다. (android studio 버젼에 따라 화면은 조금씩 달라집니다.)

 Native C++ project를 선택합니다.

그 외, 프로젝트 이름 정도만 살짝 수정하고, 기본값으로 진행을 해 보겠습니다. 언어는 Java로 했습니다.

Toolchain이 뭔지 모르겠지만, 일단 기본값으로 합니다.

프로젝트를 생성하면 아래와 같은 구조가 됩니다. 

cpp라는 폴더가 눈에 띄고, 그 속에 includes와 CMakeLists.txt, native-lib.cpp가 있네요.

CMakeLists.txt는 아마도, 프로젝트에 있는 c/c++ 파일들을 CMake로 빌드 하는데 사용 될 것 같네요.

그리고, java에는 하나의 activity가 있고, 메쏘드 중에 stringFromJNI라는 메쏘드가 일반 android app 템플릿과 달라 보입니다.

 

2. Tool 설치와 업데이트

 위에서도 나왔지만, CMake를 써서 빌드를 하기 위해 CMake가 필요합니다. 그 외 NDK 기반으로 개발하기 위해 필요한 툴들을 설치/업데이트 해 보겠습니다. sdk manager 버튼을 눌러봅니다.

프로젝트 세팅 창에서 아래 그림과 같이 필요한 툴을 설치/업데이트 합니다.

 

저는 아래와 같은 오류인지 경고인지가 나왔는데, Clang 뭐뭐뭐.... 잘 모르겠고 일반 빌드 되니까 넘어갑니다.

 

 

 

3. 앱 실행 및 프로젝트 구조

 일단 앱을 실행 해 보면, 아래와 같이 화면에 글자가 나오는 단순한 프로젝트 입니다.

 이 문자열은 c++로 만들어진 모듈에서 제공되고, 안드로이드는 c++ 코드에서 제공하는 글자를 화면의 text view에 넣어서 보여줍니다. 이처럼, c++ 부분과 android가 연동하는 아주 간단한 형태의 프로젝트 입니다.

 

 activity code를 살펴보면, text view에 글자를 할당하는 부분에서 JNI로부터 문자열을 가져오는 함수가 있습니다.

 이 함수의 선언을 잘 살펴봐야 합니다.

native라는 keyword가 있네요. 그런데, 이 함수가 구현 된 코드는 자바코드 어디서도 찾을 수가 없습니다. 그럼, c++쪽에 아마도 이 구현이 있고, 여기서는 그것을 사용하겠다고 선언하는 부분이라 볼 수 있겠네요.

 

c++ 코드를 살펴보면, 아래 함수가 있습니다. 문자열을 리턴하고 있으니, 딱 이 함수가 저 자바 함수에 대응되는 것 같은데 함수명이 전혀 다릅니다.

일단 c++ 함수 선언 형식도 낯설어서 어디까지가 지켜줘야 할 형식인지 한번 확인 해 봅시다.

당연히 안될 것 같았지만, 아래와 같이 함수를 정의했더니 빌드가 되지 않네요.

 

내용은 잘 모르겠지만, 우선은 동일한 형식으로 함수 이름과 리턴 되는 문자열을 다르게 해서 함수를 하나 정의하겠습니다. 

그리고, activity에 같은 방법으로 함수 선언부를 하나 추가합니다. 이렇게만 해도 될지, 아니면 새로 추가 된 함수와 아래 선언을 연결 시켜줄 부가적인 정보가 더 필요한지 확인 해 봅니다.

실행을 해 보니, 아래와 같이 새로 만든 함수가 연동되어 잘 실행 됩니다. 함수명이 다른데, 어떻게 연결이 되는 것일까요??

 

4. 리턴 타입

 문자열 대신 정수형을 리턴 받아서, 그 숫자에 1을 더해서 출력하도록 해 보겠습니다. activity쪽 코드는 간단하니 생략하고, 정수를 리턴하는 함수를 아래와 같이 만들어 봅니다. 

 달라진 점은 함수 선언에서 패키지 명에 해당하는 부분에 제가 임의로 글자를 적어봤고, int형을 리턴하도록 했습니다.

 

 보시다시피, jint라는 새로운 타입이 있습니다. C/C++용 타입과 그에 상응하는 JNI용 타입이 있네요. 보통 앞에 j를 붙여주면 되네요.

http://forum.falinux.com/zbxe/?mid=lecture_tip&page=7&document_srl=570118

 

강좌와 팁 - JNI programming - (2) 기본 변수형 다루기

 

forum.falinux.com

그리고, 이 함수를 호출 할 수 있는 함수를 activity에 선언했는데, 에러가 생기네요.

자동 수정 기능을 써서 어떻게 고치나 한번 보겠습니다.

아래와 같이 올바른 C/C++ 함수의 구현부가 만들어집니다.

이렇게 만들어진 코드를 보니, blablabla로 했던 부분이 패키지명과 클래스명을 꼭 넣어줘야 하는 것 같네요. 관련해서 검색을 해 보니 실제로 이런 규칙이 있습니다.

https://m.blog.naver.com/PostView.nhn?blogId=dud5243_&logNo=220517244578&proxyReferer=https%3A%2F%2Fwww.google.com%2F

 

JNI(Java Native Interface) hello-jni 샘플코드, 함수이름규칙, JNI 데이터타입

HelloJni.java 파일 위치 : android-ndk-r10e/samples/hello-jni/src/com/example/hellojni package com....

blog.naver.com

그럼 이제 int형 인자를 받아서 처리 해 주는 함수도 하나 추가 해 볼텐데, 위와 같이 자동으로 코드를 만들어주는 기능을 활용 해서 만들기 위해 activity에 먼저 int형 인자를 추가한 함수를 선언하고, 코드 수정 기능을 실행 합니다. 그러면, 아래와 같이 코드 구현부가 만들어 집니다.

 이 방법을 쓰면 훨씬 수월하게 C/C++ 함수 구현부를 만들 수 있겠네요. NDK로 되어 있는 어떤 샘플 코드를 확인 해 보니, 아래와 같이 전처리문을 정의 해 놓고 편리하게 쓰고 있네요. 즉, 함수 이름과 인자만 주면, 'Java'와 '패키지 네임', '클래스 네임'을 합쳐서 함수명을 만들어 주도록 했네요.

 

이 정도만 알아도, 이제 NDK 기반으로 만들어진 코드 분석은 어지간히 진행 할 수 있겠네요.

너무 쫄 필요 없겠습니다.

728x90
반응형

댓글