[Android] NDK를 사용한 Native 사용 방법

zunu·2025년 1월 21일

회사에서 간단한 테스트용 앱이 필요해서 급하게 알아보고 사용해보았다.

C++ 네이티브 코드를 사용하여 함수를 만들고 그 함수를 안드로이드 내에서 사용이 가능하다는 점에서 나름 매력적인 것 같다.

  1. C++ 특성상 성능 향상 및 처리 속도의 증가

  2. C++ 코드의 재사용

정도의 장점이 있는데, 나의 경우 두 번째 이유 때문에 NDK를 사용하게 되었다.

우선 NDK를 사용할 새 프로젝트를 생성해야한다.

File - New - New Project로 가면 아래와 같은 익숙한 화면이 우리를 반겨준다.

그리고 스크롤을 쭉 내려보면 Native C++이라는 프로젝트 템플릿이 보인다.

선택하고 NEXT 버튼을 눌러준다.


Name: 프로젝트 이름

Package Name: 패키지 이름

Save Location: 프로젝트를 저장할 장소

Language: 안드로이드 개발 시 사용할 코드(자바와 코틀린 중 선택.)

Minimum SDK: 최소 지원 SDK 설정


사용할 C++ 표준 라이브러리도 선택해준다. 나의 경우. 제일 최근에 나온 C++ 17로 설정했다.

그리고 Finish 버튼을 눌러주면 알아서 프로젝트를 생성한다.

다른 사전 설정없이 프로젝트를 생성하면 안드로이드 스튜디오에서 NDK 또는 CMAKE SDK가 없다면서 설치하라고 한다.

설치가 완료되면 정상 확인을 위해 빌드를 해본다. 에러 없이 빌드가 된다면 세팅이 제대로 된 것이다.

여기서 프로젝트를 살펴보면 일반적인 안드로이드 스튜디오 프로젝트에서는 볼 수 없는 패키지가 하나 있다.

바로 cpp 패키지인데, 간단히 생각해 C++ 코드가 들어갈 하나의 프로젝트라고 생각하면 된다.

처음 프로젝트를 만들고 native-lib,cpp를 들어가면 간단하게 Hello from C++ 이라는 텍스트를 출력하는 함수가 만들어져있다.

#include <jni.h>
#include <string>

extern "C" JNIEXPORT jstring JNICALL
Java_com_p_myapplication_MainActivity_stringFromJNI(
        JNIEnv* env,
        jobject /* this */) {
    std::string hello = "Hello from C++";
    return env->NewStringUTF(hello.c_str());
}

이 native-lib.cpp 파일이 안드로이드와 c++의 연결 고리라고 생각하면 된다. 이곳에서 선언해서, MainActivity에서 불러와 사용한다.

특 중요한 것이 저 함수 이름이다.

"Java_com_p_myapplication_MainActivity_stringFromJNI"

단순히 함수 이름을 뜻하는 것만이 아니라 경로까지 표시를 하는 것이다.

java/com/p/myapplication/MainActivity 에서 사용할 함수 stringFromJNI라고 생각하면 된다.

이외에 함수에서 리턴 값을 정하는 것은 JNIEXPORT 다음에 있는 jstring이다.

여기서는 jstring으로 되어 있으니 String 형태의 리턴 값이 나오게 될 것이고 jint로 되어 있다면 int 형태의 리턴 값이 나오게 될 것 이다.

또한 파라미터가 필요한 함수라면

#include <jni.h>
#include <string>

extern "C" JNIEXPORT jstring JNICALL
Java_com_p_myapplication_MainActivity_stringFromJNI(
        JNIEnv* env,
        jobject, /* this */
        jstring string_parameter,
        jint int_parameter) {
    std::string hello = "Hello from C++";
    return env->NewStringUTF(hello.c_str());
}

이런 식으로 사용하면 된다.

아직도 이해가 안될 수 있으니 자바 함수처럼 바꾸어 작성해보겠다.

String stringFromJNI(int num, String text) {
	...
    return "TEXT";
}

대충 이런 식이 될 것이다.

아무튼 이렇게 작성한 함수를 아래와같이 자바에서 불러와 사용하면 끝이다.

package com.p.myapplication;

import androidx.appcompat.app.AppCompatActivity;

import android.os.Bundle;
import android.widget.TextView;

public class MainActivity extends AppCompatActivity {

    // Used to load the 'native-lib' library on application startup.
    static {
        System.loadLibrary("native-lib");
    }

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        // Example of a call to a native method
        TextView tv = findViewById(R.id.sample_text);
        tv.setText(stringFromJNI(1, "text"));
    }

    /**
     * A native method that is implemented by the 'native-lib' native library,
     * which is packaged with this application.
     */
    public native String stringFromJNI(int num, String text); // native-lib에서 불러온 함수
}

cpp 패키지에 새로운 cpp 또는 h 파일을 생성하면 반드시 CMakeLists.txt 파일에 기재해 주어야 한다.

이런 식으로. 안 해주면 빌드시 오류가 나오니 잊어먹지 말고 반드시 해주길 바란다.

출처

profile
개발새발

0개의 댓글